if conditional in bash giving error - bash

I have a small bash script where I want to get the format of a file.
FILENAME=$1
GET_FILE_FORMAT=`file $FILENAME | grep -i data`
if[[ "$GET_FILE_FORMAT" = *data* ]]
echo "Format Data";
fi
However the output that I get is as follows
./try.bash test.data
./try.bash: line 4: if[[ test.data : data = *data* ]]: No such file or directory
Format Data
./try.bash: line 6: syntax error near unexpected token `fi'
./try.bash: line 6: `fi'

There are a couple of problems here:
You don't have any space after if.
The end of the conditional, i.e. if, isn't indicated.
To fix, say:
if [[ "$GET_FILE_FORMAT" = *data* ]]; then
To prevent getting incorrect information when the file name itself contains the string data, say:
GET_FILE_FORMAT=$(file "${FILENAME}" | awk -F: '{print $NF}')

Related

Bash Scripting note running

Given an array of string element, join all the elements of the array with spaces, convert all letters to lowercase and send the result to stdout.
Also have challenges with this "Given an array of strings, count the strings that contain at least one uppercase character and output the result to stdout."
Please any heads-up will be appreciated!
I wrote this for question 1:
#!/bin/bash
var=$(IFS='\n'; echo "$(my_array[*])")
var=$(IFS=''; echo "$((${my_arrary[#]}))")
echo $var | tr '[:upper:]' '[:lower]'
echo "$var" | awk '{print tolower($#)}')
echo result
exit 0
But got error when I ran into error as shown below:
$ bash script.sh
script.sh: line 2: my_array[*]: command not found
0
script.sh: line 6: syntax error near unexpected token `)'
script.sh: line 6: `echo "$var" | awk '{print tolower($#)}')'

Bash: Complex command in if statement

I'm writing this script, which should detect an error after the smart test is done. But I can't get it to detect any error, or not of course.
if [[ smartctl --log=selftest /dev/sda | awk 'NR>7 {print $4,$5,$6,$7}' | sed 's/offline//g; s/00%//g' != *"Completed without error"* ]; then
echo "No error detected"
else echo "Error detected"
fi
Output:
./test.sh: line 19: conditional binary operator expected
./test.sh: line 19: syntax error near `--log=selftest'
./test.sh: line 19: `if [[ smartctl --log=selftest /dev/sda | awk 'NR>7 {print $4,$5,$6,$7}' | sed 's/offline//g; s/00%//g' != *"Completed without error"* ]]; then'
So obviously I'm doing something wrong. But all the tutorials say two [[]] thingies, but I think the command is quite complex, it doesn't work... How can I make it work?
If you want to do a substring comparison, you need to pass a string on the left-hand side of the = or != operator to [[ ]].
A command substitution, $(), will replace the command it contains with its output, giving you a single string which can be compared in this way.
That is:
smartctl_output=$(smartctl --log=selftest /dev/sda | awk 'NR>7 {print $4,$5,$6,$7}' | sed 's/offline//g; s/00%//g')
if [[ "$smartctl_output" != *"Completed without error"* ]; then
: ...put your error handling here...
fi
or, a bit less readably:
if [[ "$(smartctl --log=selftest /dev/sda | awk 'NR>7 {print $4,$5,$6,$7}' | sed 's/offline//g; s/00%//g')" != *"Completed without error"* ]; then
: ...put your error handling here...
fi
You are confusing things. If the command you want to test is smartctl, don't replace it with [[. You want either or, not both. (See also e.g. Bash if statement syntax error)
Anyway, piping awk through sed and then using the shell to compare the result to another string seems like an extremely roundabout way of doing things. The way to communicate with if is to return a non-zero exit code for error.
if smartctl --log=selftest /dev/sda |
awk 'NR>7 { if ($4 OFS $5 OFS $6 OFS $7 ~ /Completed without error/) e=1; exit }
END { exit 1-e }'
then
echo "No error detected"
else
echo "Error detected"
fi

Find special character in last line of text file

I have a text file like this (e.g., a.txt):
1.1.t
1.2.m
If the last line consists of the character m, I want to echo Ok.
I tried this:
line=` awk '/./{line=$0} END{print line}' a.txt`
line1= `echo $line | grep "m"`
if [[ $line1= `:` ]] ; then
echo
else
echo "Ok"
fi
It does not work, and the error is:
bash: conditional binary operator expected
bash: syntax error near ``:`,
`if [[ $line1= `:` ]] ; then'
if [[ $line1=:]] is incorrect syntax in couple of ways as spaces around = are missing and backtick is used for command substitution
awk itself can handle this:
awk '/./{line=$0} END{print (line ~ /\.m/)? "ok" : "no"}' file
ok
You could also use tail and grep:
[[ -n $(tail -1 a.txt | grep "m$") ]] && echo "OK" || echo "FAILED"
You can use sed:
sed -n '${/m$/s/.*/OK/p;}' file
The option -n suppresses output by default. $ addresses the last line of input. In that case we check if the line ends with m through /m$/. If that is the case we substitute the line with the word OK and print it.
Btw, I was going trough your shell script, there are really too many errors to explain, the syntax error is because there is no space between $line1 and the = in the [[ ... ]] conditional. But hey, this is far from being the only problem with that script. ;)
http://www.shellcheck.net/ might be a good resource to enhance your scripts.

How to redirect grep to a while loop

Hi I have the following bash script code
group2=0
while read -r line
do
popAll=$line | cut -d "{" -f2 | cut -d "}" -f1 | tr -cd "," | wc -c
if [[ $popAll = 0 ]]; then
group2 = $((group2+2));
else
group2 = $((group2+popAll+1));
fi
done << (grep -w "token" "$file")
and I get the following error:
./parsingTrace: line 153: syntax error near unexpected token `('
./parsingTrace: line 153: `done << (grep -w "pop" "$file")'
I do not want to pipe grep to the while, because I want variable inside the loop to be visible outside
The problem is in this line:
done << (grep -w "token" "$file")
# ^^
You need to say < and then <(). The first one is to indicate the input for the while loop and the second one for the process substitution:
done < <(grep -w "token" "$file")
# ^ ^
Note however that there are many others things you want to check. See the comments for a discussion and paste the code in ShellCheck for more details. Also, by indicating some sample input and desired output I am sure we can find a better way to do this.

Cat command Unexpected delimited by end-of-file

I have the script
#!/bin/bash
set i=0;
while read line
do
echo "$line";
$i < cat "my.log" | grep -w "$line" | wc -l;
echo "$i";
if [ "$i" == 0 ]; then
cat $line << "notfound.txt"
fi
i=0;
done < "test.txt"
which is giving the error
./test.sh: line 13: warning: here-document at line 10 delimited by end-of-file (wanted `notfound.txt')
./test.sh: line 14: syntax error: unexpected end of file
My goal is to test the value of the variable i. If it is 0 then I would like to redirect the value stored in the variable $line to a file "notfound.txt"
Instead of
cat $line << "notfound.txt"
say:
echo $line > "notfound.txt"
You don't cat variables, you echo those instead. command > file would redirect the output of the command to the file, overwriting it. If you want to append the file, use >> instead.
You can learn more about redirection here.

Resources