Or statement in bash with grep [duplicate] - bash

This question already has answers here:
How to do a logical OR operation for integer comparison in shell scripting?
(8 answers)
Closed 3 years ago.
I am writing a bash script that cycles through a list of files and does something either when the file contains a certain word, or the file was created within the last X seconds. The script works fine with only the first requirement
if grep -q $error $f; then
, but I don't know how to include the "or" statement.
I have tried the following ( I am new to bash so I tried things that may not even make sense ).
FILES=logdir/*.out
OLDTIME=86400
CURTIME=$(date +%s)
error='exit'
for f in $FILES
do
FILETIME=$(stat $f -c %Y)
TIMEDIFF=$(expr $CURTIME - $FILETIME)
if [[ grep -q $error $f ]] || [[$OLDTIME -gt $TIMEDIFF ]] ; then
or
if [[ grep -q $error $f || $OLDTIME -gt $TIMEDIFF ]] ; then
gives me
./script.sh: line 12: conditional binary operator expected
./script.sh: line 12: syntax error near `-q'
and
if [ grep -q $error $f ] || [ $OLDTIME -gt $TIMEDIFF ] ; then
gives me
./script.sh: line 12: [: too many arguments
./script.sh: line 12: [: 1: unary operator expected
How can I have both conditions in the if statement?

It's easier than you think :-)
if /bin/true || /bin/false; then echo hi; fi
prints hi
if /bin/false || /bin/false; then echo hi; fi
prints nothing.
In other words, you don't need the [ or [[ operators. Just execute the commands to return their status and use || to "or" them.

Related

bash comparing variables that are integers with -gt -lt

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

Error in shell script: Integer expression expected [duplicate]

This question already has answers here:
Shell equality operators (=, ==, -eq)
(4 answers)
Closed 4 years ago.
i am studying shell script right now. I started to learn how to work with more complex if statements. What's wrong with this code bellow? I read other similar questions here in stackoverflow, but i couldnt resolve my problem. Now im verifying if the first, second or third argument is null. In the future i pretend to verify based in some regex or something like that.
Thanks!!
The code (line 9):
if [ "$1" -eq "" ] || [ "$2" -eq "" ] || [ "$3" -eq "" ] then ...
line 9: [: : integer expression expected line 9: [: : integer
expression expected line 9: [: : integer expression expected
-eq performs an arithmetic comparison between two numbers. Use = for string comparisons. Or better yet, use [[ and ==.
[[ $1 == "" ]]
[ "$1" = "" ]
You can also use -z and -n to directly test whether a value is empty/non-empty.
[[ -n $value ]] # [[ $value != "" ]]
[[ -z $value ]] # [[ $value == "" ]]
use [[ and ]] for the more modern / complex operators. This is a bashism, so beware.

Shell Error while trying to perform a IF statement

Good day.
I am trying to create a script to read each line of a specific file and then send each line to a second file depending on how many characters that line contains.
For example i have a file called numbers which contain the following information:
numbers.txt
5196803638
31995500317
5196396080
51999205240
5198158891
As you can see i have number with 8 or 9 numbers on each, i was trying to create a script that read a file line and send each number to its specific files.
!#/bin/bash
while IFS='' read -r line || [[ -n "$line" ]]; do
echo $line
if [ "${#line}"= 8 ]; then
$line> file8.txt
elif [ "${#line}"= 9 ]; then
$line> file9.txt
else
echo "Error"
fi
done < "$1"
But the only thing i get is the following
51996803638
My.sh: line 7: [: 11=: unary operator expected
My.sh: line 9: [: 11=: unary operator expected
Error
Your numbers have 10 or 11 characters. When you compare numerical values, use -eq, -ne, -lt, -gt, -le, -ge.
while IFS='' read -r line || [[ -n "$line" ]]; do
echo $line
echo "Length = ${#line}"
if [ ${#line} -eq 10 ]; then
echo $line >> file10.txt
elif [ ${#line} -eq 11 ]; then
echo $line >> file11.txt
else
echo "Error"
fi
done < "$1"
The shell's tokenizer is white-space sensitive. Use spaces around =, as in
if [ "${#line}" = 8 ]; then
$line> file8.txt
elif [ "${#line}" = 9 ]; then
$line> file9.txt
else
echo "Error"
fi
Or, what about this, which I find more readable/maintainable/extendable:
case ${#line} in
(8) $line > file8.txt;;
(9) $line > file9.txt;;
(*) echo Error;;
esac

An error with if statement in shell scripting

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

Ubuntu shell script getting error

I am developing simple shell script which copy all my present directory files to backup directory which will be exist in present working directory. now i'm getting error when i pass more then one condition in if.
#!/bin/bash
filename=nx.pdf
for i in *;
do
echo $i;
if [ $i == backup || $i == $filename ] ; then
echo "Found backup."
else
echo "Part 2"
cp -rf $i backup
fi
done
I am getting error
asd.sh: line 6: [: missing `]'
asd.sh: line 6: ==: command not found
Part 2
deployee.sh
asd.sh: line 6: [: missing `]'
asd.sh: line 6: ==: command not found
Part 2
The compare operator is = (as defined in POSIX). But == works on some shells as well.
Something like this should work:
if [ $i = backup ] || [ $i = $filename ] ; then
You should quote $i in "". Otherwise you get syntax errors for filenames with blanks.
To be able to use || and && in conditions, you have to use the double square brackets:
if [[ $i == backup || $i == $filename ]] ; then

Resources