Reputation: 721
I have a file like this
File name : hello.txt
{1:ABC}{2:BCD}{3:{108:20140619-2}}{4:
:97A::Hi//12345
:97A::Hi//12345
:93B::Hello//FAMT/00000,
:16S:FIN
-}{5:{CHK:BDG6789}}{S:{ABC:}{DEF:S}{WOM:ONHGRT}}
Now basically i'm checking for the existence of $ symbol and as well as :97A: AND im using the below if statement.
if [ `grep -c '\$' hello.txt` -gt 0 ] && [ `grep -c ":97A:" hello.txt` -gt 1 ]
then
echo "condition satisfied"
else
echo "condition not satisfied"
fi
if i execute this im getting condition satisifed echo statement. But id should be the other way round :( since im putting AND condition. Please help on this.
Upvotes: 1
Views: 421
Reputation: 45596
Using awk
and reading the file only once:
if awk '/[$]/{d++} /:97A:/{o++} END{exit !(d && o>1)}' hello.txt; then
echo "condition satisfied"
else
echo "condition not satisfied"
fi
Upvotes: 1
Reputation: 2541
"i'm checking for the existence of $ symbol"
First condition won't match because there is no "$" sign anywhere in your input, therefore output of first grep is 0. As 0 isn't greater than 0, the result is "false". Consequently, the second clause won't be executed at all. "Condition is not satisfied" because your requirement for "satisfied" is: input contains both "$" AND ":97A:".
For a result whether grep matched any line, you don't need to count number of matches.
if grep -q '\$' file; then ...
is a way to use result of grep in a conditional statement without rube-goldbergismns
Upvotes: 1
Reputation: 78740
I recommend executing your grep
commands in a subshell with the $
syntax, then doing the comparison. In my opinion this is the cleaner way and requires you to be less of an escape artist.
if [ $(grep -c '\$' hello.txt) -gt 0 ] && [ $(grep -c ":97A:" hello.txt) -gt 1 ]
then
echo "condition satisfied"
else
echo "condition not satisfied"
fi
For your hello.txt
the output will be:
>> bash test.bash
condition not satisfied
Since there's no dollar sign in your file
[ $(grep -c '\$' hello.txt) -gt 0 ]
will test
[ 0 -gt 0 ]
and yield false, while
[ $(grep -c ':97A' hello.txt) -gt 1 ]
will test
[ 2 -gt 1 ]
and yield true. Finally, false && true will yield false and the second echo statement will be executed.
Upvotes: 1
Reputation: 7959
Replace grep -c '\$' hello.txt
by grep -c '\\$' hello.txt
Then it will work as desired.
ex:
bash -x test.sh
++ grep -c '\$' hello.txt
+ '[' 0 -gt 0 ']'
+ echo 'condition not satisfied'
condition not satisfied
PS: bash -x is your friend :)
Upvotes: 1
Reputation: 7562
I also don't understand what you're asking, but from your code I conclude that you have troubles grepping for the dollar sign. I guess you need to escape the backslash as well if you use backticks:
$ echo 'foo$bar' > dollar.txt
$ echo 'foo_bar' > no_dollar.txt
$ [ `grep -c '\$' dollar.txt` -gt 0 ] && echo 1
1
$ [ `grep -c '\$' no_dollar.txt` -gt 0 ] && echo 1
1
$ [ `grep -c '\\$' dollar.txt` -gt 0 ] && echo 1
1
$ [ `grep -c '\\$' no_dollar.txt` -gt 0 ] && echo 1
$ [ `grep -c '\\$' no_dollar.txt` -gt 0 ] || echo 0
0
alternatively, use $()
instead of backticks
Upvotes: 1