Searching multiple patterns (words) with ack?
Asked Answered
S

4

17

I want to search multiple patterns in a directory containing recursive directories and files.

I know command for grep which is as follows

grep -e '(pattern1)|(pattern2)'

or

grep -r -E  'string1|string2|string3' /var/www/http

What is the command for that using ack or ag?

Schwann answered 9/10, 2014 at 10:2 Comment(0)
W
19

This should be enough:

ack -R 'string1|string2'

As -R is the default, you can omit it:

ack 'string1|string2'

From man ack:

-r, -R, --recurse

Recurse into sub-directories. This is the default and just here for compatibility with grep. You can also use it for turning --no-recurse off.


If you want to get the pattern from a file, say /path/to/patterns.file, you can use:

ack "$(cat /path/to/patterns.file)"

or equivallently:

ack "$(< /path/to/patterns.file)"

I cannot find an exact equivalent to grep -f.

Wahoo answered 9/10, 2014 at 10:10 Comment(8)
What do you mean? To store the output in a file or to read the patterns from a file? Please provide the equivalent in grep to know exactly to what functionality you are referring to.Wahoo
read the patterns from a file something like grep -f pattern.txt also if I keeping them in a file is it necessary to start pattern with some special character like ^Schwann
@SandipPingle uhms, I cannot find an equivalent, so I suggest getting it with ack "$(< /path/to/patterns.file)" *. See update.Wahoo
ack "$(cat /path/to/patterns.file)" * is working fine, with by keeping patterns in file | separated like pat1|pat2Schwann
do you know any efficient way to keep output also in a file currently I am using ack "$(< /path/to/patterns.file)" * > output.txt but problem is reading/editing output file is difficult.Schwann
@SandipPingle you can maybe use -l, --sort-files, etc. It really depends on how you want the output. Take a good look at man ack.Wahoo
is the * really needed to search in the current folder and all its subfolders ? works here without (might have been different when the question was asked, though...)Brigandine
@Brigandine you are right, it is not necessary, like when you do grep -R .... Using it does not harm because it expands to all the elements in the current dir, but at the end this is something that -R already does. Updated.Wahoo
I
7

The ack command can also string along with pipes. For example the first ack finds files containing pattern1 then pipe that to another ack to search just those files for pattern2

ack -l 'pattern1' | ack -x 'pattern2'

The -l parameter means to just list the matching files (instead of the matching text). The -x parameter means to search just the files piped to it. This is similar to narrowing down the files for the next ack search.

ack -l 'pattern1' | ack -xl 'pattern2' | ack -x 'pattern3'

This is an AND operator and not the OR operator given in the other solutions.

Infarction answered 30/8, 2019 at 0:14 Comment(1)
JEEZ! how often was I screwing around with find and xargs and what not when ack alone just does the trick, too! :+1:Brigandine
P
1

For ag, as of verion 0.19.2 the default is to search in directories and files recursively.

To search for multiple patterns, you can use similiar syntax as ack

ag 'pattern1|pattern2'

will search for both pattern1 and pattern2.

In case you don't want to search recursively, you can set the search depth to 1 by the switch --depth NUM

Therefore,

ag 'pattern1|pattern2' --depth 1

will only search in the current directory for both patterns.

Pierette answered 17/6, 2015 at 18:0 Comment(0)
R
1

I don't know why but for my use case, the pipe solution didn't work.

I simply used the output of ack -l as the input to grep. For example, to quickly find all Javascript files containing string 1 and string 2:

grep "string 2" `ack -l --js "string 1"`
Rattlehead answered 6/2, 2019 at 20:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.