binary operator expected using ! -z?
Olivia Zamora
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"
fiI 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).
2 Answers
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
Barthen
$ g=$(grep -ni foo myfile)
$ echo $g
1:foo 3:Fooso
$ [ ! -z $g ]
bash: [: 1:foo: binary operator expectedThe 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 emptyHowever 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 I figured it out. I needed to change:
if [ ! -z $g ]; thento
if [ ! -z "$g" ]; thenHowever, 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!