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.

Post History

77%
+5 −0
Q&A grep AND search for multiple words in files

From your description ... 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. ... I co...

posted 1y ago by Dirk Herrmann‭  ·  edited 1y ago by Dirk Herrmann‭

Answer
#8: Post edited by user avatar Dirk Herrmann‭ · 2023-06-13T08:33:36Z (over 1 year ago)
Small fix, confused foo and bar at one place
  • From your description ...
  • > 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.
  • ... I conclude that you are interested in files that contain both 'foo' and 'bar', but not necessarily on the same line. Thus I will discuss that aspect first.
  • **'foo' and 'bar' possibly on different lines:**
  • As an alternative to the approach proposed by @Canina this can be solved by a combination of `find` and `grep` in the following way:
  • ```sh
  • find . -type f -exec grep -wq foo {} \; -exec grep -wl bar {} \;
  • ```
  • The first `-exec` condition of the `find` command (`-exec grep -q foo {} \;`) succeeds on files containing 'foo': The `-q` option instructs `grep` to be quiet and only report whether a match was found in the return status.
  • The second `-exec` condition (`-exec grep -l bar {} \;`) operates on the files for which the first `-exec` condition was true (i.e. which contained 'foo'). This time `grep` searches for 'bar', and due to the `-l` option prints the name of the file where a match was found.
  • Note that I left out the `-n` option here, as it does not seem to make sense in this case: There are possibly two lines involved (or even more if 'foo' or 'bar' occur more often), but only one would be printed.
  • **'foo' and 'bar' on the same line:**
  • The solution that you have written is able to find lines where 'foo' and 'bar' appear on the same line:
  • ```sh
  • grep -rnw . -e 'foo' | grep -e 'bar'
  • ```
  • The first `grep` searches for all lines with 'foo' and prints the lines that were found to `stdout` prefixed with the file name and the line number. This output is then piped to the second `grep`, which filters for those lines containing 'bar'.
  • This will (mostly) work for the case where you want to find files with 'foo' and 'bar' appearing on the same line. It will fail if one of the file names happens to contain 'foo' as a word.
  • An alternative approach to find lines where 'foo' and 'bar' are expected on the same line is the following, which checks for lines with 'foo' followed by 'bar' or lines with 'bar' followed by 'foo':
  • ```sh
  • grep -rn -E -e '(\<foo\>.*\<bar\>)|(\<bar\>.*\<foo\>)' .
  • ```
  • From your description ...
  • > 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.
  • ... I conclude that you are interested in files that contain both 'foo' and 'bar', but not necessarily on the same line. Thus I will discuss that aspect first.
  • **'foo' and 'bar' possibly on different lines:**
  • As an alternative to the approach proposed by @Canina this can be solved by a combination of `find` and `grep` in the following way:
  • ```sh
  • find . -type f -exec grep -wq foo {} \; -exec grep -wl bar {} \;
  • ```
  • The first `-exec` condition of the `find` command (`-exec grep -q foo {} \;`) succeeds on files containing 'foo': The `-q` option instructs `grep` to be quiet and only report whether a match was found in the return status.
  • The second `-exec` condition (`-exec grep -l bar {} \;`) operates on the files for which the first `-exec` condition was true (i.e. which contained 'foo'). This time `grep` searches for 'bar', and due to the `-l` option prints the name of the file where a match was found.
  • Note that I left out the `-n` option here, as it does not seem to make sense in this case: There are possibly two lines involved (or even more if 'foo' or 'bar' occur more often), but only one would be printed.
  • **'foo' and 'bar' on the same line:**
  • The solution that you have written is able to find lines where 'foo' and 'bar' appear on the same line:
  • ```sh
  • grep -rnw . -e 'foo' | grep -e 'bar'
  • ```
  • The first `grep` searches for all lines with 'foo' and prints the lines that were found to `stdout` prefixed with the file name and the line number. This output is then piped to the second `grep`, which filters for those lines containing 'bar'.
  • This will (mostly) work for the case where you want to find files with 'foo' and 'bar' appearing on the same line. It will fail if one of the file names happens to contain 'bar' as a word.
  • An alternative approach to find lines where 'foo' and 'bar' are expected on the same line is the following, which checks for lines with 'foo' followed by 'bar' or lines with 'bar' followed by 'foo':
  • ```sh
  • grep -rn -E -e '(\<foo\>.*\<bar\>)|(\<bar\>.*\<foo\>)' .
  • ```
#7: Post edited by user avatar Dirk Herrmann‭ · 2023-06-13T06:46:39Z (over 1 year ago)
  • From your description ...
  • > 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.
  • ... I conclude that you are interested in files that contain both 'foo' and 'bar', but not necessarily on the same line. Thus I will discuss that aspect first.
  • **'foo' and 'bar' possibly on different lines:**
  • As an alternative to the approach proposed by @Canina this can be solved by a combination of `find` and `grep` in the following way:
  • ```sh
  • find . -type f -exec grep -wq foo {} \; -exec grep -wl bar {} \;
  • ```
  • The first `-exec` condition of the `find` command (`-exec grep -q foo {} \;`) succeeds on files containing 'foo': The `-q` option instructs `grep` to be quiet and only report whether a match was found in the return status.
  • The second `-exec` condition (`-exec grep -l bar {} \;`) operates on the files for which the first `-exec` condition was true (i.e. which contained 'foo'). This time `grep` searches for 'bar', and due to the `-l` option prints the name of the file where a match was found.
  • Note that I left out the `-n` option here, as it does not seem to make sense in this case: There are possibly two lines involved (or even more if 'foo' or 'bar' occur more often), but only one would be printed.
  • **'foo' and 'bar' on the same line:**
  • The solution that you have written is able to find lines where 'foo' and 'bar' appear on the same line:
  • ```sh
  • grep -rnw . -e 'foo' | grep -e 'bar'
  • ```
  • The first `grep` searches for all lines with 'foo' and prints the lines that were found to `stdout` prefixed with the file name and the line number. This output is then piped to the second `grep`, which filters for those lines containing 'bar'.
  • This will (mostly) work for the case where you want to find files with 'foo' and 'bar' appearing on the same line. It will fail if one of the file names happens to contain 'foo' as a word. And, if several lines in a file fulfill the condition, all of them will be printed - which may or may not be what you expect.
  • An alternative approach to find lines where 'foo' and 'bar' are expected on the same line is the following, which checks for lines with 'foo' followed by 'bar' or lines with 'bar' followed by 'foo':
  • ```sh
  • grep -rn -E -e '(\<foo\>.*\<bar\>)|(\<bar\>.*\<foo\>)' .
  • ```
  • From your description ...
  • > 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.
  • ... I conclude that you are interested in files that contain both 'foo' and 'bar', but not necessarily on the same line. Thus I will discuss that aspect first.
  • **'foo' and 'bar' possibly on different lines:**
  • As an alternative to the approach proposed by @Canina this can be solved by a combination of `find` and `grep` in the following way:
  • ```sh
  • find . -type f -exec grep -wq foo {} \; -exec grep -wl bar {} \;
  • ```
  • The first `-exec` condition of the `find` command (`-exec grep -q foo {} \;`) succeeds on files containing 'foo': The `-q` option instructs `grep` to be quiet and only report whether a match was found in the return status.
  • The second `-exec` condition (`-exec grep -l bar {} \;`) operates on the files for which the first `-exec` condition was true (i.e. which contained 'foo'). This time `grep` searches for 'bar', and due to the `-l` option prints the name of the file where a match was found.
  • Note that I left out the `-n` option here, as it does not seem to make sense in this case: There are possibly two lines involved (or even more if 'foo' or 'bar' occur more often), but only one would be printed.
  • **'foo' and 'bar' on the same line:**
  • The solution that you have written is able to find lines where 'foo' and 'bar' appear on the same line:
  • ```sh
  • grep -rnw . -e 'foo' | grep -e 'bar'
  • ```
  • The first `grep` searches for all lines with 'foo' and prints the lines that were found to `stdout` prefixed with the file name and the line number. This output is then piped to the second `grep`, which filters for those lines containing 'bar'.
  • This will (mostly) work for the case where you want to find files with 'foo' and 'bar' appearing on the same line. It will fail if one of the file names happens to contain 'foo' as a word.
  • An alternative approach to find lines where 'foo' and 'bar' are expected on the same line is the following, which checks for lines with 'foo' followed by 'bar' or lines with 'bar' followed by 'foo':
  • ```sh
  • grep -rn -E -e '(\<foo\>.*\<bar\>)|(\<bar\>.*\<foo\>)' .
  • ```
#6: Post edited by user avatar Dirk Herrmann‭ · 2023-06-13T06:46:04Z (over 1 year ago)
  • From your description ...
  • > 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.
  • ... I conclude that you are interested in files that contain both 'foo' and 'bar', but not necessarily on the same line. Thus I will discuss that aspect first.
  • **'foo' and 'bar' possibly on different lines:**
  • As an alternative to the approach proposed by @Canina this can be solved by a combination of `find` and `grep` in the following way:
  • ```sh
  • find . -type f -exec grep -wq foo {} \; -exec grep -wl bar {} \;
  • ```
  • The first `-exec` condition of the `find` command (`-exec grep -q foo {} \;`) succeeds on files containing 'foo': The `-q` option instructs `grep` to be quiet and only report whether a match was found in the return status.
  • The second `-exec` condition (`-exec grep -l bar {} \;`) operates on the files for which the first `-exec` condition was true (i.e. which contained 'foo'). This time `grep` searches for 'bar', and due to the `-l` option prints the name of the file where a match was found.
  • Note that I left out the `-n` option here, as it does not seem to make sense in this case: There are possibly two lines involved (or even more if 'foo' or 'bar' occur more often), but only one would be printed.
  • **'foo' and 'bar' on the same line:**
  • The solution that you have written is able to find lines where 'foo' and 'bar' appear on the same line:
  • ```sh
  • grep -rnw . -e 'foo' | grep -e 'bar'
  • ```
  • The first `grep` searches for all lines with 'foo' and prints the lines that were found to `stdout` prefixed with the file name and the line number. This output is then piped to the second `grep`, which filters for those lines containing 'bar'.
  • This will (mostly) work for the case where you want to find files with 'foo' and 'bar' appearing on the same line. It will fail if one of the file names happens to contain 'foo' as a word.
  • An alternative approach to find lines where 'foo' and 'bar' are expected on the same line is the following, which checks for lines with 'foo' followed by 'bar' or lines with 'bar' followed by 'foo':
  • ```sh
  • grep -rn -E -e '(\<foo\>.*\<bar\>)|(\<bar\>.*\<foo\>)' .
  • ```
  • From your description ...
  • > 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.
  • ... I conclude that you are interested in files that contain both 'foo' and 'bar', but not necessarily on the same line. Thus I will discuss that aspect first.
  • **'foo' and 'bar' possibly on different lines:**
  • As an alternative to the approach proposed by @Canina this can be solved by a combination of `find` and `grep` in the following way:
  • ```sh
  • find . -type f -exec grep -wq foo {} \; -exec grep -wl bar {} \;
  • ```
  • The first `-exec` condition of the `find` command (`-exec grep -q foo {} \;`) succeeds on files containing 'foo': The `-q` option instructs `grep` to be quiet and only report whether a match was found in the return status.
  • The second `-exec` condition (`-exec grep -l bar {} \;`) operates on the files for which the first `-exec` condition was true (i.e. which contained 'foo'). This time `grep` searches for 'bar', and due to the `-l` option prints the name of the file where a match was found.
  • Note that I left out the `-n` option here, as it does not seem to make sense in this case: There are possibly two lines involved (or even more if 'foo' or 'bar' occur more often), but only one would be printed.
  • **'foo' and 'bar' on the same line:**
  • The solution that you have written is able to find lines where 'foo' and 'bar' appear on the same line:
  • ```sh
  • grep -rnw . -e 'foo' | grep -e 'bar'
  • ```
  • The first `grep` searches for all lines with 'foo' and prints the lines that were found to `stdout` prefixed with the file name and the line number. This output is then piped to the second `grep`, which filters for those lines containing 'bar'.
  • This will (mostly) work for the case where you want to find files with 'foo' and 'bar' appearing on the same line. It will fail if one of the file names happens to contain 'foo' as a word. And, if several lines in a file fulfill the condition, all of them will be printed - which may or may not be what you expect.
  • An alternative approach to find lines where 'foo' and 'bar' are expected on the same line is the following, which checks for lines with 'foo' followed by 'bar' or lines with 'bar' followed by 'foo':
  • ```sh
  • grep -rn -E -e '(\<foo\>.*\<bar\>)|(\<bar\>.*\<foo\>)' .
  • ```
#5: Post edited by user avatar Dirk Herrmann‭ · 2023-06-13T06:44:50Z (over 1 year ago)
  • From your description ...
  • > 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.
  • ... I conclude that you are interested in files that contain both 'foo' and 'bar', but not necessarily on the same line. Thus I will discuss that aspect first.
  • **'foo' and 'bar' possibly on different lines:**
  • As an alternative to the approach proposed by @Canina this can be solved by a combination of `find` and `grep` in the following way:
  • ```sh
  • find . -type f -exec grep -wq foo {} \; -exec grep -wl bar {} \;
  • ```
  • The first `-exec` condition of the `find` command (`-exec grep -q foo {} \;`) succeeds on files containing 'foo': The `-q` option instructs `grep` to be quiet and only report whether a match was found in the return status.
  • The second `-exec` condition (`-exec grep -l bar {} \;`) operates on the files for which the first `-exec` condition was true (i.e. which contained 'foo'). This time `grep` searches for 'bar', and due to the `-l` option prints the name of the file where a match was found.
  • Note that I left out the `-n` option here, as it does not seem to make sense in this case: There are possibly two lines involved (or even more if 'foo' or 'bar' occurs more often), but only one would be printed.
  • **'foo' and 'bar' on the same line:**
  • The solution that you have written is able to find lines where 'foo' and 'bar' appear on the same line:
  • ```sh
  • grep -rnw . -e 'foo' | grep -e 'bar'
  • ```
  • The first `grep` searches for all lines with 'foo' and prints the lines that were found to `stdout` prefixed with the file name and the line number. This output is then piped to the second `grep`, which filters for those lines containing 'bar'.
  • This will (mostly) work for the case where you want to find files with 'foo' and 'bar' appearing on the same line. It will fail if one of the file names happens to contain 'foo' as a word.
  • An alternative approach to find lines where 'foo' and 'bar' are expected on the same line is the following, which checks for lines with 'foo' followed by 'bar' or lines with 'bar' followed by 'foo':
  • ```sh
  • grep -rn -E -e '(\<foo\>.*\<bar\>)|(\<bar\>.*\<foo\>)' .
  • ```
  • From your description ...
  • > 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.
  • ... I conclude that you are interested in files that contain both 'foo' and 'bar', but not necessarily on the same line. Thus I will discuss that aspect first.
  • **'foo' and 'bar' possibly on different lines:**
  • As an alternative to the approach proposed by @Canina this can be solved by a combination of `find` and `grep` in the following way:
  • ```sh
  • find . -type f -exec grep -wq foo {} \; -exec grep -wl bar {} \;
  • ```
  • The first `-exec` condition of the `find` command (`-exec grep -q foo {} \;`) succeeds on files containing 'foo': The `-q` option instructs `grep` to be quiet and only report whether a match was found in the return status.
  • The second `-exec` condition (`-exec grep -l bar {} \;`) operates on the files for which the first `-exec` condition was true (i.e. which contained 'foo'). This time `grep` searches for 'bar', and due to the `-l` option prints the name of the file where a match was found.
  • Note that I left out the `-n` option here, as it does not seem to make sense in this case: There are possibly two lines involved (or even more if 'foo' or 'bar' occur more often), but only one would be printed.
  • **'foo' and 'bar' on the same line:**
  • The solution that you have written is able to find lines where 'foo' and 'bar' appear on the same line:
  • ```sh
  • grep -rnw . -e 'foo' | grep -e 'bar'
  • ```
  • The first `grep` searches for all lines with 'foo' and prints the lines that were found to `stdout` prefixed with the file name and the line number. This output is then piped to the second `grep`, which filters for those lines containing 'bar'.
  • This will (mostly) work for the case where you want to find files with 'foo' and 'bar' appearing on the same line. It will fail if one of the file names happens to contain 'foo' as a word.
  • An alternative approach to find lines where 'foo' and 'bar' are expected on the same line is the following, which checks for lines with 'foo' followed by 'bar' or lines with 'bar' followed by 'foo':
  • ```sh
  • grep -rn -E -e '(\<foo\>.*\<bar\>)|(\<bar\>.*\<foo\>)' .
  • ```
#4: Post edited by user avatar Dirk Herrmann‭ · 2023-06-13T06:44:28Z (over 1 year ago)
  • From your description ...
  • > 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.
  • ... I conclude that you are interested in files that contain both 'foo' and 'bar', but not necessarily on the same line. Thus I will discuss that aspect first.
  • **'foo' and 'bar' possibly on different lines:**
  • As an alternative to the approach proposed by @Canina this can be solved by a combination of `find` and `grep` in the following way:
  • ```sh
  • find . -type f -exec grep -wq foo {} \; -exec grep -wl bar {} \;
  • ```
  • The first `-exec` condition of the `find` command (`-exec grep -q foo {} \;`) succeeds on files containing 'foo': The `-q` option instructs `grep` to be quiet and only report whether a match was found in the return status.
  • The second `-exec` condition (`-exec grep -l bar {} \;`) operates on the files for which the first `-exec` condition was true (i.e. which contained 'foo'). This time `grep` searches for 'bar', and due to the `-l` option prints the name of the file where a match was found.
  • Note that I left out the `-n` option here, as it does not seem to make sense in this case: There are possibly two lines involved, but only one would be printed.
  • **'foo' and 'bar' on the same line:**
  • The solution that you have written is able to find lines where 'foo' and 'bar' appear on the same line:
  • ```sh
  • grep -rnw . -e 'foo' | grep -e 'bar'
  • ```
  • The first `grep` searches for all lines with 'foo' and prints the lines that were found to `stdout` prefixed with the file name and the line number. This output is then piped to the second `grep`, which filters for those lines containing 'bar'.
  • This will (mostly) work for the case where you want to find files with 'foo' and 'bar' appearing on the same line. It will fail if one of the file names happens to contain 'foo' as a word.
  • An alternative approach to find lines where 'foo' and 'bar' are expected on the same line is the following, which checks for lines with 'foo' followed by 'bar' or lines with 'bar' followed by 'foo':
  • ```sh
  • grep -rn -E -e '(\<foo\>.*\<bar\>)|(\<bar\>.*\<foo\>)' .
  • ```
  • From your description ...
  • > 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.
  • ... I conclude that you are interested in files that contain both 'foo' and 'bar', but not necessarily on the same line. Thus I will discuss that aspect first.
  • **'foo' and 'bar' possibly on different lines:**
  • As an alternative to the approach proposed by @Canina this can be solved by a combination of `find` and `grep` in the following way:
  • ```sh
  • find . -type f -exec grep -wq foo {} \; -exec grep -wl bar {} \;
  • ```
  • The first `-exec` condition of the `find` command (`-exec grep -q foo {} \;`) succeeds on files containing 'foo': The `-q` option instructs `grep` to be quiet and only report whether a match was found in the return status.
  • The second `-exec` condition (`-exec grep -l bar {} \;`) operates on the files for which the first `-exec` condition was true (i.e. which contained 'foo'). This time `grep` searches for 'bar', and due to the `-l` option prints the name of the file where a match was found.
  • Note that I left out the `-n` option here, as it does not seem to make sense in this case: There are possibly two lines involved (or even more if 'foo' or 'bar' occurs more often), but only one would be printed.
  • **'foo' and 'bar' on the same line:**
  • The solution that you have written is able to find lines where 'foo' and 'bar' appear on the same line:
  • ```sh
  • grep -rnw . -e 'foo' | grep -e 'bar'
  • ```
  • The first `grep` searches for all lines with 'foo' and prints the lines that were found to `stdout` prefixed with the file name and the line number. This output is then piped to the second `grep`, which filters for those lines containing 'bar'.
  • This will (mostly) work for the case where you want to find files with 'foo' and 'bar' appearing on the same line. It will fail if one of the file names happens to contain 'foo' as a word.
  • An alternative approach to find lines where 'foo' and 'bar' are expected on the same line is the following, which checks for lines with 'foo' followed by 'bar' or lines with 'bar' followed by 'foo':
  • ```sh
  • grep -rn -E -e '(\<foo\>.*\<bar\>)|(\<bar\>.*\<foo\>)' .
  • ```
#3: Post edited by user avatar Dirk Herrmann‭ · 2023-06-13T06:43:04Z (over 1 year ago)
Improved find command, added discussion about finding foo and bar on the same line
  • From your description
  • > 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.
  • I conclude that you are interested in files that contain both 'foo' and 'bar', but not necessarily on the same line.
  • As an alternative to the approach proposed by @Canina this can be solved by a combination of `find` and `grep` in the following way:
  • ```sh
  • find . -exec grep -q foo {} \; -exec grep -l bar {} \;
  • ```
  • The first condition of the `find` command (`-exec grep -q foo {} \;`) succeeds on files containing 'foo': The `-q` option instructs `grep` to be quiet and only report whether a match was found in the return status.
  • The second condition (`-exec grep -l bar {} \;`) operates on the files for which the first condition was true (i.e. which contained 'foo'). This time `grep` searches for 'bar', and due to the `-l` option prints the name of the file where a match was found.
  • From your description ...
  • > 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.
  • ... I conclude that you are interested in files that contain both 'foo' and 'bar', but not necessarily on the same line. Thus I will discuss that aspect first.
  • **'foo' and 'bar' possibly on different lines:**
  • As an alternative to the approach proposed by @Canina this can be solved by a combination of `find` and `grep` in the following way:
  • ```sh
  • find . -type f -exec grep -wq foo {} \; -exec grep -wl bar {} \;
  • ```
  • The first `-exec` condition of the `find` command (`-exec grep -q foo {} \;`) succeeds on files containing 'foo': The `-q` option instructs `grep` to be quiet and only report whether a match was found in the return status.
  • The second `-exec` condition (`-exec grep -l bar {} \;`) operates on the files for which the first `-exec` condition was true (i.e. which contained 'foo'). This time `grep` searches for 'bar', and due to the `-l` option prints the name of the file where a match was found.
  • Note that I left out the `-n` option here, as it does not seem to make sense in this case: There are possibly two lines involved, but only one would be printed.
  • **'foo' and 'bar' on the same line:**
  • The solution that you have written is able to find lines where 'foo' and 'bar' appear on the same line:
  • ```sh
  • grep -rnw . -e 'foo' | grep -e 'bar'
  • ```
  • The first `grep` searches for all lines with 'foo' and prints the lines that were found to `stdout` prefixed with the file name and the line number. This output is then piped to the second `grep`, which filters for those lines containing 'bar'.
  • This will (mostly) work for the case where you want to find files with 'foo' and 'bar' appearing on the same line. It will fail if one of the file names happens to contain 'foo' as a word.
  • An alternative approach to find lines where 'foo' and 'bar' are expected on the same line is the following, which checks for lines with 'foo' followed by 'bar' or lines with 'bar' followed by 'foo':
  • ```sh
  • grep -rn -E -e '(\<foo\>.*\<bar\>)|(\<bar\>.*\<foo\>)' .
  • ```
#2: Post edited by user avatar Dirk Herrmann‭ · 2023-06-11T19:27:18Z (over 1 year ago)
  • From your description
  • > 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.
  • I conclude that you are interested in files that contain both `foo` and `bar`, but not necessarily on the same line.
  • As an alternative to the approach proposed by @Canina this can be solved by a combination of `find` and `grep` in the following way:
  • ```sh
  • find . -exec grep -q foo {} \; -exec grep -l bar {} \;
  • ```
  • The first condition of the `find` command (`-exec grep -q foo {} \;`) succeeds on files containing "foo": The `-q` option instructs `grep` to be quiet and only report whether a match was found in the return status.
  • The second condition (`-exec grep -l bar {} \;`) operates on the files for which the first condition was true (i.e. which contained "foo"). This time grep searches for "bar", and due to the `-l` option prints the name of the file where a match was found.
  • From your description
  • > 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.
  • I conclude that you are interested in files that contain both 'foo' and 'bar', but not necessarily on the same line.
  • As an alternative to the approach proposed by @Canina this can be solved by a combination of `find` and `grep` in the following way:
  • ```sh
  • find . -exec grep -q foo {} \; -exec grep -l bar {} \;
  • ```
  • The first condition of the `find` command (`-exec grep -q foo {} \;`) succeeds on files containing 'foo': The `-q` option instructs `grep` to be quiet and only report whether a match was found in the return status.
  • The second condition (`-exec grep -l bar {} \;`) operates on the files for which the first condition was true (i.e. which contained 'foo'). This time `grep` searches for 'bar', and due to the `-l` option prints the name of the file where a match was found.
#1: Initial revision by user avatar Dirk Herrmann‭ · 2023-06-11T19:25:39Z (over 1 year ago)
From your description

 > 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.

I conclude that you are interested in files that contain both `foo` and `bar`, but not necessarily on the same line.

As an alternative to the approach proposed by @Canina this can be solved by a combination of `find` and `grep` in the following way:
```sh
find . -exec grep -q foo {} \; -exec grep -l bar {} \;
```
The first condition of the `find` command (`-exec grep -q foo {} \;`) succeeds on files containing "foo": The `-q` option instructs `grep` to be quiet and only report whether a match was found in the return status.

The second condition (`-exec grep -l bar {} \;`) operates on the files for which the first condition was true (i.e. which contained "foo").  This time grep searches for "bar", and due to the `-l` option prints the name of the file where a match was found.