2

I have this find command:

$ find . -name '*.jar' -exec grep -Hls BuildConfig {} \;

I need to execute this command for each result of command find above:

$ zip -d RESULTPATH "*/BuildConfig.class"

So can I do this with for loop or not? Can I create .sh file that will be doing what I need? Thanks!

user269721
  • 33
  • 3
  • Relevant: https://stackoverflow.com/q/9612090/1531971 –  Oct 11 '17 at 17:28
  • Is `RESULTPATH` intended to be "each of the files identified by the `find` command"? Also, a `.jar` file is a zip. Do you mean `grep -z`? Also, what's with the quotes on your `zip` line? – ghoti Oct 11 '17 at 17:42
  • yes, on resultpath's place must be the paths that was found by find command. Quotes are missing – user269721 Oct 11 '17 at 17:50
  • Sounds like you want to grep through not the jar file itself, but the list of filenames it contains. That requires a rather different command. – Charles Duffy Oct 11 '17 at 18:10

2 Answers2

2

A clean way to run a command for each result of a grep command with xargs, is using the -Z or --null flag with grep to make the results terminated by null, and the -0 flag with xargs so that it expects values terminated by null, like this:

find . -name '*.jar' -exec grep -Z BuildConfig {} \; | xargs -0 zip -d RESULTPATH "*/BuildConfig.class

I removed the Hls flags because they all seem pointless (even harmful) in your use case.

But I'm afraid this will not actually work for your case, because a .jar file is usually a binary file (zipped archive of Java classes), so I don't think the grep will ever match anything. You can give zgrep a try to search inside the jars.

Jens
  • 570
  • 3
  • 11
janos
  • 120,954
  • 29
  • 226
  • 236
0

The grep command has two channels for information out of it. The first and most obvious one is of course stdout, where it sends matches it finds. But if it finds no matches, it also uses an exit value > 0 to inform you. Combined with the -q (quiet) option, you can use this as a more intelligent option for find:

$ find . -name '*.jar' -exec zgrep -sq BuildConfig {} \; -exec zip -d {} "*/BuildConfig.class" \;

This assumes that you want to search through the compressed file using grep -Z, of course. :)

Or for easier reading:

find . -name '*.jar' \
  -exec zgrep -sq BuildConfig {} \; \
  -exec zip -d {} "*/BuildConfig.class" \;

Find operates by running each test in order. You can think of the options as a series of filters; the -name option is the first filters, and a file only gets passed to the second -exec if the preceding -exec exited without errors.

ghoti
  • 45,319
  • 8
  • 65
  • 104