I am not sure why my code below generates this error (standard_in) 1: syntax error -bash: [: -eq: unary operator expected . Can someone please help me figure out the problem here? Thanks!
#!/bin/bash
BAMLINES=4.47264e+09
FQ1LINES=4000000
FQ2LINES=4000000
DEBUG=1
if [ ! -z ${DEBUG} ]; then
echo "${BAMLINES} lines in .bam"
echo "${FQ1LINES} lines in all ${FQ_OUT1} files"
echo "${FQ2LINES} lines in all ${FQ_OUT2} files"
if [ $(echo "scale=2;${FQ1LINES}/${BAMLINES} > 0.40" | bc) -eq 0 ]; then
echo "Warning, FQ1 file contains ${FQ1LINES} lines - less than 40% of the number of reads of .bam file"
fi
if [ $(echo "scale=2;${FQ2LINES}/${BAMLINES} > 0.4" | bc) -eq 0 ]; then
echo "Warning, FQ2 file contains ${FQ2LINES} lines - less than 40% of the number of reads of .bam file"
fi
fi
$ echo "scale=2;($FQ1LINES/$BAMLINES) > 0.40"
scale=2;(4000000/) > 0.40
# ..............^^
You want to use either BAMLINE or BAMLINES but not both.
$ echo "scale=2;($FQ1LINES/$BAMLINES) > 0.40" | bc
(standard_in) 1: parse error
Because of that error, the output of $(echo ... | bc) is empty, and then [ only gets 2 arguments. When [ gets 2 arguments, the first operator is expected to be a unary operator (like -z is) -- -eq is not a unary operator.
You need to quote any variables/command expansions within [...]. In this case you'd get a different but more meaningful error:
$ [ "$(echo "scale=2;${FQ1LINES}/${BAMLINES} > 0.40" | bc)" -eq 0 ]
(standard_in) 1: parse error
bash: [: : integer expression expected
Or use [[...]] and you'll just see the bc error
$ [[ $(echo "scale=2;${FQ1LINES}/${BAMLINES} > 0.40" | bc) -eq 0 ]]
(standard_in) 1: parse error
Related
I'm trying to make a bash script that reads integers from a file (one number per line, name of the file is passed as the script argument), finds maximum, minimum and sum. I've got a problem with the part, where I'm comparing variables, though. Code below (I've skipped here the part which checks whether the file exists or is empty):
#!/bin/bash
min=`cat "$1" | head -n 1`
max=$min
sum=0
lw=`cat "$1" | wc -l`
while [ $lw -gt 0 ];
do
num=`cat "$1" | tail -n $lw | head -n 1`
if [ "$num" -gt "$max" ]
then
max=$num
elif [ "$num" -lt "$min" ]
then
min=$num
fi
sum=$[sum+num]
lw=$[$lw-1]
done
echo "Maximum: $max"
echo "Minimum: $min"
echo "Sum: $sum"
With this code I'm getting errors in lines 13 and 16: [: : integer expression expected
If I change the comparision part inside the while loop to:
if [ $num -gt $max ]
then
max=$num
elif [ $num -lt $min ]
then
min=$num
fi
I'm getting errors:
line 13: [: -gt: unary operator expected
line 16: [: -lt: unary operator expected
What am I doing wrong? I'm a total newbie in bash, so I'll be extremely grateful for any help.
Data that I used for testing:
5
6
8
2
3
5
9
10
Probably your input file contains DOS line endings or other improper formatting. Your code should work for well-formed inputs.
However, the proper way to loop over the lines in a file is
#!/bin/bash
min=$(sed 1q "$1")
max=$min
sum=0
while read -r num; do
if [ "$num" -gt "$max" ]
then
max=$num
elif [ "$num" -lt "$min" ]
then
min=$num
fi
((sum+=num))
done<"$1"
echo "Maximum: $max"
echo "Minimum: $min"
echo "Sum: $sum"
Notice also that backticks and $[[...]]] use syntax which has been obselescent for decades already.
My guess would be that the expression
num=`cat "$1" | tail -n $lw | head -n 1`
assigns to num some value that is not a number in one of the iterations. I would suggest adding echo "$num" in the prev line to check this assumption
Another thing: instead of reading lines using cat | tail | head it is easier to read file line by line using the following syntax
while IFS= read -r line
do
echo "$line"
done < "$input"
This will read contents of input file into line variable.
See here for explanations about IFS= and -r https://www.cyberciti.biz/faq/unix-howto-read-line-by-line-from-file/ - both of them not really necessary in your case
So I have a variable that I want to compare with another number in an if statement.
b=8.25
if [ $(echo "$b < 10" | bc) -ne 0 ]; then
echo "hey"
fi
I get the following error
(standard_in) 1: syntax error
I know the issue is having the b variable inside, how can I make it so that I can maintain it in there?
Please help
Your script file probably has DOS-style CRLF line endings:
$ b=8.25
$ if [ $(echo "$b < 10" | bc) -ne 0 ]; then
> echo "hey"
> fi
hey
$ b=$'8.25\r'
$ if [ $(echo "$b < 10" | bc) -ne 0 ]; then
> echo "hey"
> fi
(standard_in) 1: illegal character: ^M
bash: [: -ne: unary operator expected
Run dos2unix on your script file.
Store the comparison in a variable separateley
b=8.25
# Capture output outside the if
comparison=$(echo "$b < 10" | bc)
# Use the output in the if
if [ $comparison -ne 0 ]; then
echo "hey"
fi
I have the following instruction:
if [[ ! `wc -l <<< $SILENT_LOG` -eq 1 -o ! `wc -l <<< $ACTIVE_LOG` -eq 1 ]] then
echo "There should be only a silent report log file!" >> $DEST_DIR/$RESULT_FILE
OK=0;
fi
OK should be set to 0 when SILENT_LOG or ACTIVE_LOG have 0 or more lines. The problem is that the following error is raised:
**./reportComparator.sh: line 26: syntax error near `-o'
./reportComparator.sh: line 26: `if [[ ! `wc -l <<< $SILENT_LOG` -eq 1 -o ! `wc -l <<< $ACTIVE_LOG` -eq 1 ]] then'**
Also, I tried to replace wc -l <<< $SILENT_LOG with echo $SILENT_LOG | wc-l but it still does not work.
First, the following syntax will not work:
$ [[ 1 -eq 1 -o 2 -eq 2 ]]
bash: syntax error in conditional expression
bash: syntax error near `-o'
In bash, you have two choices:
$ [[ 1 -eq 1 || 2 -eq 2 ]]
$ [ 1 -eq 1 -o 2 -eq 2 ]
For compatibility with plain POSIX shells, neither of the above should be used, the former because plain POSIX does not support [[ and the latter because plain POSIX shells cannot parse such long tests reliably. Instead use:
$ [ 1 -eq 1 ] || [ 2 -eq 2 ]
For the second issue, let's create a variable with three lines:
$ silent_log='one
> two
> three'
Now observe:
$ wc -l <<<$silent_log
1
$ wc -l <<<"$silent_log"
3
If you want the lines counted correctly, you need to double-quote your variables.
You have some syntax issues in your code.
For [[...] you can use:
if [[ $(wc -l < "$SILENT_LOG") -eq 1 || $(wc -l < "$ACTIVE_LOG") -eq 1 ]]; then
echo "There should be only a silent report log file!" >> $DEST_DIR/$RESULT_FILE
OK=0
fi
I'm trying to write a shell script, but it's giving me a syntax error at the following command:
if [[ -n ${array[$x1]} -a [ expr length "$x1" -gt 2 ] ]]
This is the error message:
./project: line 45: syntax error in conditional expression
./project: line 45: syntax error near `-a'
./project: line 45: ` if [[ -n ${array[$x1]} -a [ expr length "$x1" -gt 2 ] ]]'
What am I doing wrong?
Use && not -a in [[ ]]
Also, expr length won't do what you expect here. The better approach, since you're already using bash extensions, is to use the ${#param} expansion to get the length of $param, and evaluate that within a math context, like so:
if [[ -n ${array[$x1]} ]] && (( ${#x1} > 2 )); then
...
fi
I have these if conditions, but it has compile errors. How can I fix it?
if [ $DEVICE_ID == "" ]; then
I get error:
line 63: [: ==: unary operator expected
if [ 'ls -l Mytest*.log | wc -l' -eq 1 ]; then
i get error:
line 68: [: ls -l Kernel*.log | wc -l: integer expression expected
Quote the variable:
if [ "$DEVICE_ID" == "" ]; then
But it would be better to do:
if [ -z "$DEVICE_ID" ];
The second error is that you need to use backquotes:
if [ $(ls -l Mytest*.log | wc -l) -eq 1 ]; then
If you're using bash, use double brackets for conditional expressions: they are smarter about unquoted variables
if [[ $DEVICE_ID = "" ]]; then ...
would work (note: = instead of == for plain string equality instead of pattern matching)
For presence of files use an array
shopt -s nullglob
files=( *.log )
if (( ${#files[#]} > 0 )); the. Echo "there are log files"; fi