I've been using ACK for searching my code base, and it's a wonderful tool. However, it has (in my opinion) one important limitation - it does not allow multi-line matching of regular expressions.
To overcome that limitation, I'd like to filter a set of files which contain a certain expression, and then filter them again looking for a second expression (given that both expressions are most likely not on the same line). I've tried running the following command, with no success (it returns nothing):
ack -l --type=java "(List|Collection|Map|Set)" | ack --type=java "String"
And I'd rather not use grep
, since I want to limit my searches to java files, ignoring .cvs dirs, .svn dirs, etc. (something ack
does by default) Any ideas?
Your current command line is executing ack on the list of files, not using the list of matched files as another set of files to inspect. That is, it'd be the same as doing
ack -l --type=java "(List|Collection|Map|Set)" > files
ack "String" files
xargs
is the tool you want to use to treat the output from the first command as a set of files with which the second ack invocation can run.
ack --print0 -l --type=java "(List|Collection|Map|Set)" | xargs -0 ack "String"
The --print0
separates the filenames by null characters to ensure that xargs gets the correct filename (in case there are odd characters in it). The -0
flag to xargs tells it to expect the filenames to be null separated.