I have a bunch of zipped up log files and I want to search them all for a string. I tried this but it's not working:

find ./ -name "*.log.zip" -exec gzip -dc {} | grep ERROR \;

It's giving me:

find: incomplete statement
grep: can't open ;

What I want is, for each .log.zip file, unzip it and grep the output for "ERROR". Doing this on AIX, for what it's worth.

  • btw, I've managed to get the result I wanted by putting the -exec commands in a separate script and then using -exec script {} \; But I'd still like to know why the above doesn't work and if it's possible to do what I want without creating an intermediate script. – mluisbrown Apr 8 '13 at 10:45

There is an error in your syntax. Find is looking for \; or \+, but reads |. Grep is trying to open a file called ";". The difference between terminating -exec with a semicolon or a plus is running the command once for all files (+) and running the command once for every file (;).

Try this:

find ./ -name "*.log.zip" -exec zcat {} \+ | grep ERROR
# or
find ./ -name "*.log.zip" -exec sh -c 'zcat {} | grep ERROR' \;
  • The semicolon must be escaped with \ because it means something to the shell (end statement). The plus does not have to be escaped with bash. – Ярослав Рахматуллин Apr 8 '13 at 11:12
  • The first option works if I use gzip -dc but not with zcat, which gives a foo.log.zip.Z: No such file or directory error. The second option I'd already tried, and doesn't work as the {} substitution doesn't work. If I use gzip it gives a {}.gz: No such file or directory for each file. For zcat: {}.Z: No such file or directory. – mluisbrown Apr 8 '13 at 14:11
  • Then use the first version with gzip -dc. It's not entirely misguided to assume that most command line questions here are about GNU tools, specify the platform you are on and the version of the tools if that in not your case. – Ярослав Рахматуллин Apr 8 '13 at 14:51
  • I specified that I was running on AIX in the original post. However, the question of gzip or zcat is not that relevant. I'm more curious as to why in your 2nd solution the {} substitution does not happen, especially as the \+ find syntax cannot be applied to all such similar situations. – mluisbrown Apr 8 '13 at 15:02
  • Sorry for being inattentive, clearly I didn't recognize the OS tag. My guess is that the find on AIX reads the option to the -c argument of sh as a literal string and does no substitution. You could try something like -exec sh -c 'zcat '{}'| grep ERROR', but it's probably more effective to read the notes about -exec option in the manual than trying to "fool" the command. You could also use xargs, which has the -I flag (GNU find, but maybe AIX too) that specifies what {} should be. Such as: find /dir | xargs -I% gzip -dc % | grep ERROR. – Ярослав Рахматуллин Apr 8 '13 at 16:20

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.