`echo` is stripping newlines in Bash script [duplicate] - bash

This question already has answers here:
I just assigned a variable, but echo $variable shows something else
(7 answers)
When should I double-quote a parameter expansion? [duplicate]
(1 answer)
Closed 5 months ago.
If I have a file containing newlines, the below script will output the file as is, with newlines:
#!/bin/bash
FOO=$(cat filename.yaml)
echo "$FOO"
but
#!/bin/bash
FOO=$(cat filename.yaml)
FOO=$(echo $FOO)
echo "$FOO"
outputs the file all on one line. How come?

I do not recommend storing the contents of entire files in a single variable. In my experience that can have unpredictable results.
/usr/bin/env bash -x
index=$(wc -l filename.yaml | cut -d' ' -f1)
count=1
next () {
[[ "${count}" -lt "${index}" ]] && main
[[ "${count}" -eq "${index}" ]] && exit 0
}
main () {
line=$(sed -n "${count}p" filename.yaml)
echo "var${count}=${line}" >> varfile
count=$(($count+1))
next
}
next
If you source varfile at the start of another script, it will give you every line from that file, in its' own variable.

Related

how to handle filename that has special characters (hypen) in bash scripting? [duplicate]

This question already has answers here:
When to wrap quotes around a shell variable?
(5 answers)
Closed 5 months ago.
I have a bash function that crawls through the current directory of the bash script and find for files that have a certain file extensions. Everything is working fine until I have files that have bash-related special characters like '-' in the filename.
My question is, how do I handle the dashes in the filename? Thank you in advance!
Directory
./1a.log
./1b.log
./1c.log
./1d file.log
./1e file_working.log
./1f-notworking.log #error
logparser.sh
read_files() {
files=()
file_ext="${FILE##*.}"
if [ -f "$FILE" ] && [[ $file_ext == log ]]; then
msg "${RED}Parsing file: ${CYAN}$FILE"
files+=($FILE)
elif [ -d "$FILE" ]; then
msg "${RED}Parsing file: ${BLUE}$FILE"
for FILENAME in "$FILE"/*; do
dir_ext="${FILENAME##*.}"
if [ -f $FILENAME ] && [[ $dir_ext == log ]]; then
files+=($FILENAME)
fi
done
else
msg "${RED}Unable to process: ${CYAN}$FILE .Skipping"
fi
}
Tracestack
[: syntax error: `-' unexpected
After reading the post recommended by #GordonDavisson , the issue that I have faced is due to not quoting the variable that is storing my filename.
This is because "parameter expansions are subjected to both word-splitting and pathname expansion" [https://stackoverflow.com/questions/55023461/when-should-i-double-quote-a-parameter-expansion]. By quoting, it preserves the literal content of the parameter.
"General rule: quote it if it can either be empty or contain spaces (or any whitespace really) or special characters (wildcards). Not quoting strings with spaces often leads to the shell breaking apart a single argument into many" [https://stackoverflow.com/a/10067297/8638278]
logparser.log
read_files() {
files=()
file_ext="${FILE##*.}"
if [ -f "$FILE" ] && [[ $file_ext == log ]]; then
msg "${RED}Parsing file: ${CYAN}$FILE"
files+=("$FILE")
elif [ -d "$FILE" ]; then
msg "${RED}Parsing file: ${BLUE}$FILE"
for FILENAME in "$FILE"/*; do
dir_ext="${FILENAME##*.}"
if [ -f "$FILENAME" ] && [[ $dir_ext == log ]]; then
files+=("$FILENAME")
fi
done
else
msg "${RED}Unable to process: ${CYAN}$FILE .Skipping"
fi
}
#!/bin/sh -x
find . | sed -n '/*.log/p' > stack
cat > ed1 <<EOF
1p
q
EOF
cat > ed2 <<EOF
1d
wq
EOF
next () {
[[ -s stack ]] && main
exit 0
}
main () {
line=$(ed -s stack < ed1)
msg "${RED}Parsing file: ${CYAN}$line"
ed -s stack < ed2
next
}
next
This exclusively uses files with a log extension, so you don't need to check.

bash setting variable getting error command not found [duplicate]

This question already has answers here:
Indirect variable assignment in bash
(7 answers)
Closed 9 months ago.
I'm writing one small bash script for my Project
but i getting some errors
#!/bin/bash
count=$(cat Downloads/datei.csv | wc -l);
for((i=115;i<="122";i++)); do
line$i=$(sed -n $i"p" Downloads/datei.csv);
echo "line$i";
done
i trying to get every line from CSV in some variable
The erroĊ•
count.sh: line 4: line115=: command not found
if [[ -z "line$i" ]];
then
echo "$i is empty";
else
echo "$i is NOT empty";
fi
the second code gives me the same error
Suggest compose the code together, just update line$i to a temporary normal variable without other var like line_get.
One more thing, you need to update -z "line$i" to -z "$line_get". As in bash, you should use $ and the var name to get the value.
Looks like:
#!/bin/bash
count=$(cat Downloads/datei.csv | wc -l)
for((i=115;i<=122;i++)); do
line_get=$(sed -n $i"p" Downloads/datei.csv)
if [[ -z "$line_get" ]];
then
echo "$i is empty"
else
echo "$i is NOT empty"
fi
done
If you need to dynamic generate the variable name. Try this:
declare "line$i=$(sed -n $i"p" Downloads/datei.csv)"
var="line$i"
echo "${!var}"
And echo "line$i"; just print the text like line115 but not the value of the variable line$1.

regex on variable in bash script [duplicate]

This question already has answers here:
bash script do not save output file although required
(3 answers)
Closed 1 year ago.
I am trying to cut out the prefix from a variable that represents path.
Currently this is my code:
for f in /Users/username/Documents/Dev/beneficiary-service/src/main/helm/*
do
echo $f
if [[ $f == 'values'* ]]
then
yq d -i $f 'resources.'
fi
done
I printed $f to see its output. I expected it to be ONLY the filename, without the path (values-stg.yaml).
However, this is the output:
+ echo /Users/username/Documents/Dev/beneficiary-service/src/main/helm/values-stg.yaml
/Users/username/Documents/Dev/beneficiary-service/src/main/helm/values-stg.yaml
+ [[ /Users/username/Documents/Dev/beneficiary-service/src/main/helm/values-stg.yaml == \v\a\l\u\e\s* ]]
And also, the "if" statement will never be true, because it considers values* literally as is and not as "anything that starts with values"
Path expansion includes the whole path specified. You can remove it using parameter expansion
[[ ${f##*/} == values* ]]
the "if" statement will never be true
That's not true. Quoting values is not needed, though, as none of the characters is special.
Use Basename - demonstration below - assigned output of basename "${f}" (in case of white space in file names)
for f in /Users/username/Documents/Dev/beneficiary-service/src/main/helm/*
do
echo $f
bf=$(basename "${f}") ; echo ${bf}
if [[ ${bf} == 'values'* ]]
then
echo yq d -i ${bf} 'resources.'
fi
done

How to compare a variable to a string in bash? [duplicate]

This question already has answers here:
How do I compare two string variables in an 'if' statement in Bash? [duplicate]
(12 answers)
Closed 2 years ago.
here is how i tried it
while IFS= read line
do
var=$(cut -d ":" -f 3 $line)
if [ "$var" = "L2" ]
then :here is my action:
fi
done < myfile.txt
What i want to do is read a file line by line, read the third word of each line, and do a special action if the third word = a certaine string, i've tried a lot of syntax but it doesn't work. i've also tried to echo "$var" just to see if my variable get the right value, and it does. i don't know what to do anymore
It is better to use double brackets for if condition & for String comparison double equals (==)
And the line which has "cut" command wouldn't have worked. Please find below the corrected code which is working.
while IFS= read line
do
echo "Line is $line"
var=`echo $line | cut -d ":" -f 3`
echo $var
if [[ "$var" == "L2" ]]
then
echo "Some Action"
fi
done < myfile.txt

Comparing two variables in IF condition inside While loop in bash script [duplicate]

This question already has answers here:
Bash comparison operator always true
(1 answer)
How to assign the output of a Bash command to a variable? [duplicate]
(5 answers)
Closed 2 years ago.
i am trying to execute a IF condition inside a while loop, But the IF condition isn't working as variables aren't expanding! kindly guide me through the proper way to compare two variables in IF condition
Note - if you can see the error log - DATE was expanding thou! problem with mdate
DATE=`date +"%Y-%m-%d"`
cat path/temp_b | while read file
do
echo 'phase2'
mtime=$(stat -c '%y' $Src_Dir/$file)
echo $mtime
mdate= echo $mtime | cut -d ' ' -f1
echo $mdate
echo $DATE
if ["$mdate"=="$DATE"]; then
"$file" > path/tempc
else
echo 'hi'
fi
done
**Error log -
phase2
2020-05-07 05:22:28.000000000 -0400
2020-05-07
2020-07-21
./test1.ksh: line 37: [==2020-07-21]: command not found
hi**
Change your if statement like:
if [ "$mdate" == "$DATE" ]; then
Explanation: if in bash needs to have square brackets, operator, and operand to be space-separated.

Resources