Communities

Writing
Writing
Codidact Meta
Codidact Meta
The Great Outdoors
The Great Outdoors
Photography & Video
Photography & Video
Scientific Speculation
Scientific Speculation
Cooking
Cooking
Electrical Engineering
Electrical Engineering
Judaism
Judaism
Languages & Linguistics
Languages & Linguistics
Software Development
Software Development
Mathematics
Mathematics
Christianity
Christianity
Code Golf
Code Golf
Music
Music
Physics
Physics
Linux Systems
Linux Systems
Power Users
Power Users
Tabletop RPGs
Tabletop RPGs
Community Proposals
Community Proposals
tag:snake search within a tag
answers:0 unanswered questions
user:xxxx search by author id
score:0.5 posts with 0.5+ score
"snake oil" exact phrase
votes:4 posts with 4+ votes
created:<1w created < 1 week ago
post_type:xxxx type of post
Search help
Notifications
Mark all as read See all your notifications »
Q&A

Welcome to Software Development on Codidact!

Will you help us build our independent community of developers helping developers? We're small and trying to grow. We welcome questions about all aspects of software development, from design to code to QA and more. Got questions? Got answers? Got code you'd like someone to review? Please join us.

Comments on grep AND search for multiple words in files

Parent

grep AND search for multiple words in files

+9
−0

I have text (xml actually) files. Some files contain 'foo', some contain 'bar', some contain neither and some contain both. It's the both I'm interested in.

How do I do an AND search on words in files in folders (recursively) with grep? I'm using git bash in windows, so either a cygwin or win10 solution works.

I had thought pipeing to grep would work as it seems to be the solution for multiple text on a line, but I don't think I've changed it to work for files correctly.

This is what I tried:

$ grep -rnw . -e 'foo' | grep -e 'bar'

Can someone tell me how to fix my grep call?

History
Why does this post require moderator attention?
You might want to add some details to your flag.
Why should this post be closed?

0 comment threads

Post
+9
−0

Between-lines relations are not easy to look for with grep, which is a line filter. You could use a regex that spans lines, but I find this annoying because of all the flags you have to set.

Grep has a switch for printing the filenames instead of matching lines. You can put each in a file. Once you have both files, you can use comm to do the union.

grep -r . -e 'foo' > foo.txt
grep -r . -e 'bar' > bar.txt
comm foo.txt bar.txt -12

If you don't want the temp files, you can use the command inline: https://linux.codidact.com/posts/288328/288329#answer-288329 However, I simply put the files in /tmp/ where they get automatically wiped at next system shutdown.

History
Why does this post require moderator attention?
You might want to add some details to your flag.

1 comment thread

Likely no need for temporary files if you're using bash (3 comments)
Likely no need for temporary files if you're using bash
Canina‭ wrote 11 months ago · edited 11 months ago

There is very likely no need for (explicit) temporary files if you are using bash. Instead, you might try:

comm <(grep -r . -e 'foo') <(grep -r . -e 'bar') -12

which should have the same effect.

matthewsnyder‭ wrote 11 months ago

That command looks confusing and difficult to type/edit to me, which is why I used the form that I did. The temp files are not a problem if you put them in /tmp/, they'll get cleaned up automatically at next boot.

__blackjack__‭ wrote 11 months ago

What's confusing/difficult about it? The < should be known from redirecting IO, which your solution also uses, and the parenthesis are known from running something in a subshell.

Also when or even if the /tmp/ directory gets cleaned up depends on the distribution. Even if it is on reboot, that might be quite some time on servers.