beyondgrep / website

The source code for the beyondgrep.com website
https://beyondgrep.com/
37 stars 20 forks source link

FAQ: How do I search for dogs and cats on the same line? #101

Open petdance opened 7 years ago

petdance commented 7 years ago

From @petdance on July 27, 2012 13:30

Andy gave the short answer. Here's longer form ...

I'm trying to search for two words in a line (order is not important). I know I can just use two runs of Ack, and pipe them to each other. ~/ack-standalone.pl cat * | ~/ack-standalone.pl dog However, this means I lose the nice friendly file names and line numbers.

you can use flags to require or suppress file, line, and even color despite pipe.

The first call on it's own will have the filenames and line numbers, however, once I pipe through, I lose those, since the second ack only sees the piped input.

it will pass thru the file & line ... which better not match dog or you see them all cats anyway!

While it's sometimes slower with lots of long lines, you can say ack '(cat._dog)|(dog.cat)' (it will be faster than ack|ack on older windows that defer the piped command ! ) or slightly more efficiently ack '(?:cat.?dog)|(?:dog._?cat)' (since you don't care which of two dogs is found after a cat, you can take first and forward scan instead of backtracking)

You might think of doing a prescan ... ack 'cat|dog' | ack '(cat._dog|dog._cat)' BUT THAT WON'T HELP as .* will only backtrack seeking dog once it's found a cat or vice versa.

If efficiency of doing it in one pass is required, you can drop to native perl to put && between two regexs as you instinctively want to do - perl -nle 'print "$ARGV:$.: $_" if /cat/ && /dog/;' -e 'close ARGV if eof;' * ( can omit close statement if omiting $. linenumbers; it's required to reset linenumbers on each file. see perldoc -e eof.) ( If your ack would have -i ignore case, the native perl needs /cat/i && /dog/i or /(?i)cat/ && /(?i)dog/) )

It doesn't really help here but in some complex cases combining results of multiple ack passes is usefull, if most lines are discarded ... can get duplicates if lines match more than one way, which may be a feature. (ack 'cat._dog'; ack 'dog._cat') | sort

add flags for 2nd :field: numeric if alphabetic line#s are a problem in your usage

Note that the && gives different solutions if the two words can overlap, like /proper/ && /pert/ matches "property", and won't require a second "per" match. Use of boundaries will prevent /(?x) \b pert \b/ matching "property" and thus require separate words, and will prevent false positives on "dogged" and "concatenate" as well. (ack '\b(cat)\b.\b(dog)\b' ; ack '\b(dog)\b.\b(cat)\b' ) | sort

This is becoming a FAQ, maybe we can put it on webpage && manpage ?

Copied from original issue: petdance/ack2#139

petdance commented 7 years ago

From @hoelzro on July 27, 2012 13:32

@petdance Throw it up on the GH wiki?

petdance commented 7 years ago

I'm thinking we need App::Ack::FAQ. That way ack --faq can generate the FAQ, and we can also pod2html it onto betterthangrep.com.

petdance commented 7 years ago

From @hoelzro on September 6, 2013 12:38

Reminds me of #141.

n1vux commented 5 years ago

this is covered in Cookbook #26 also, but yes should be in FAQ (with link to Cookbook).

This also would interact with proposed $patA --and $patB feature #172