5

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

4 Answers 4

8

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"
Sign up to request clarification or add additional context in comments.

1 Comment

You don't have to change the quotes, this is perfectly valid bash: "$(cat textfile.txt | grep "search string")"
2

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

2 Comments

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 $?.
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.
2
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.

1 Comment

elegance. somewhere along the line, someone tried to turn bash into perl [[$( unfortunately.
2

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.