views:

45

answers:

4

I'm trying to run some shell command if a string is not present in a text file. If I paste this line into the command line if gives me an error.

if [ $(cat textfile.txt | grep "search string") -eq "" ]; then; echo "some string"; fi;

Error:

-bash: [: -eq: unary operator expected
A: 

The grep command will return 0 if the requested lines are found (1 if not, 2 if an error), so you can just use:

grep "search string" textfile.txt >/dev/null 2>&1
if [[ $? -ne 0 ]] ; then
    echo 'Not found'
fi

If you really wanted to use strings (and you probably shouldn't), you should quote them so that you don't get too many arguments for the [ command:

if [ "$(cat textfile.txt | grep 'search string')" == "" ] ; then
    echo "It's not there!"
fi
paxdiablo
I didn't downvote, but your answer is far from optimal: There is no need to do redirections because `grep` has a `-q` option, and Bash can test for the return value of a command without resorting to `$?`.
Philipp
That's okay, Philipp. Not all greps have those options (I still work with a few legacy UNIXes) and I wouldn't be shell scripting for efficiency anyway. I'll be incorporating your answer into my (modern) scripts in future so +1 for that.
paxdiablo
+2  A: 

If you use [] for comparison you need to use = instead of -eq. You also need some quotes.

if [ "$(cat textfile.txt | grep 'search string')" = "" ]; then; echo "some string"; fi;

Note that grep can take a filename as argument so the cat is unnecessary. You can also directly use the return value of grep: grep returns 1 if the search string is not found.

if [ "$(grep 'search string' textfile.txt)" ]; then
  echo "some string";
fi

An even more compact way would be to use logical and &&.

grep "search string" textfile.txt && echo "some string"
honk
+2  A: 
grep -F -q -e 'search string' textfile.txt || echo 'Not found'

Note:

  • -F prevents the interpretation of the search string as a regular expression.
  • -q suppresses all output and returns immediately after the first instance was found, making the search much faster if the string occurs at the beginning of a large file.
  • -e specifies the pattern explicitly, allowing patterns that start with a dash.
  • Use single quotes unless you want variable substitutions.
Philipp
elegance. somewhere along the line, someone tried to turn bash into perl `[[$(` unfortunately.
msw
A: 

No need for the square brackets in this case. Since [ is actually a command, any command can be used where you would use it. So here, we can use grep. There's no need to use cat since grep will accept filenames as arguments. Also, you have two too many semicolons.

if grep -q "search string" textfile.txt; then echo "some string"; fi

or

if grep "search string" textfile.txt > /dev/null 2>&1; then echo "some string"; fi
Dennis Williamson