I'm using this command to search *.jar files for java classes, and I only get the name of the jars that contain those classes:

grep -ral --include=*.jar SignonEJB .

How can I also get the class names in the output?


You passed the -l option, telling grep to only list the file names. That's the names of the .jar files, there are no other files involved.

If you want grep to output the class names, you need to remove -l. But that will print a lot of other junk on the same “line”, because the jars are binary files, not organized by lines. (With GNU grep, you need to pass -a to get that output and not just “Binary file … matches”.)

With GNU grep, one possibility is to match the full class name and pass -o to output just that:

grep -rao --include='*.jar' '[0-9A-Z_a-z]*SignonEJB[0-9A-Z_a-z]*' .

or if you want the packages as well

grep -rao --include='*.jar' '[$./0-9A-Z_a-z]*SignonEJB[0-9A-Z_a-z]*' .

Another approach is to run strings on the files first to extract printable strings. (The two commands are equivalent; the sed version chokes on \& and newline, the awk version supports all characters.)

find . -name '*.jar' -exec sh -c 'strings "$0" | grep SignonEJB | sed "s&^&$0&"' {} \;
find . -name '*.jar' -exec sh -c 'strings "$0" | jar=$0 awk "/SignonEJB/ {print ENVIRON[\"jar\"] \":\" $0}"' {} \;

Alternatively (and strictly speaking, more reliably, even though using grep is unlikely to turn up false positives), use unzip to list the file names, and filter that.

find . -name '*.jar' -exec sh -c 'unzip -l -- "$0" | grep SignonEJB' {} \;
  • The awk one supports all characters but backslash (which is why I use ENVIRON in the solution I gave). Note that it's jar paths we're talking of here, not class paths. May 21 '13 at 6:35

Maybe (with GNU tools):

grep -ralZ --include='*.jar' SignonEJB . |
  xargs -r0IJ unzip -l J '*SignonEJB*.class'

Or, maybe a bit more reliable and with an output easier to read:

find . -name '*.jar' -exec sh -c 'export i; for i do
    zipinfo -1 "$i" | awk '\''/SignonEJB.*\.class$/{
      print ENVIRON["i"] ": " $0}'\''; done' sh {} +

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.