1

I tried searching for similar problems, but can't find one that makes sense for my code. I just started about 2 weeks ago, so that may just be an inability to understand migrating answers for one case to another.

I have a code to look up all directories in a file and search each file for a word input, then eventually put any of the files with non-blank outputs into a file.

I've been using the grep line:

g=$(grep -ni "$word" $myfile)

if [ ! -z $g ]; then

echo "the file inside is: $myfile"

fi

I can put the complete code up, but this is the error:

/home/anthony/myscripts/wordturbo3.sh: line 22: [: 17:chemistry: binary operator expected

(for the word=chemistry, program=wordturbo3.sh)

This error only populates after I use the grep command with the ! -z qualifiers. The answer key I have writes it a little differently: it uses an if-else command (if -z, else) instead of (! -z) for just an if portion (no else). This seems to require that my if condition, -z, have an output in order to function (such as echo "this file is empty").

However, I am looking through many more files than the example and would like to not have to echo "this file is empty" hundreds of times just so that I can accomplish the "else" portion of the command. Therefore, I was simply trying to circumvent this need by using (! -z) for just the if portion.

It accomplishes what I want, but it first spits out 17 or so lines of the "binary operator expected."

Is there a simple workaround to this?

Thank you in advance for the advice.

edit: oh, and I found a suggestion online to use -n instead of -z for indicate "contains information" rather than "empty" but this didn't seem to work. The program didn't work when I replaced (! -z) with (-n).

0
2

Probably the issue is that your grep returns multiple matches, and the unquoted $g inside [ ! -z $g ] is undergoing word splitting.

Ex. given

$ cat myfile
foo
bar
Foo
Bar

then

$ g=$(grep -ni foo myfile)
$ echo $g
1:foo 3:Foo

so

$ [ ! -z $g ]
bash: [: 1:foo: binary operator expected

The error message is because -z is a unary operator i.e. it expects a single argument; since you have given two arguments to [ ... ] it expects you to have used a binary operator (like -eq).

If you quote the variable expansion i.e. "$g", all the matches returned by grep will be treated as a single argument, so the -z unary test will work:

$ [ ! -z "$g" ] && echo "non empty"
non empty

However you don't need any of this - instead, just check the exit status of grep itself:

$ if grep -qi foo myfile; then echo "foo is in myfile"; fi
foo is in myfile
2
  • Yes, you are right. It was the quoted "$g" that caused the error. I'm trying to understand your final line- what is -q? Is that "not empty"? – izardle Apr 17 '20 at 15:19
  • @izardle the -q tells grep to "be quiet" - it doesn't output anything, but its exit status will be TRUE (zero) if a match was found and FALSE (non zero) otherwise. It's also more efficient as it will exit on the first match. See man grep. – steeldriver Apr 17 '20 at 15:47
0

I figured it out. I needed to change:

if [ ! -z $g ]; then

to

if [ ! -z "$g" ]; then

However, I don't quite understand why yet. I'll keep looking on the web, but if anyone has any thoughts, I'd appreciate it.

Thank you!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.