From a directory, I need to find all files that contain a decimal numbers say 42.7 AND the keyword “foo” or “goo”. How could I achieve that?
Suppose I have a directory with three files
file1.txt ======= double x = 2.7 foo(); file2.txt =========== double u = 5.7 file3.txt =========== goo(42.0);
The search command should give file1.txt and file3.txt. What is a search command to achieve this?
i searched for the solutions but all I could find deal with having the patterns simultaneously appearing in the same line. Also I got difficulty in dealing with the decimal dot.
Advertisement
Answer
Use 2 grep -l
commands to list the file names (not the matched lines) that contain the regex. Connect them by xargs
, for example like so:
grep -Pl '(d+[.]?d*|d*[.]?d+)' file?.txt | xargs grep -Pl '(foo|goo)'
Example:
Create the input files. I use a few more examples in addition to the ones listed in the question to illustrate the patterns/files that are found:
cat > file1.txt <<EOF double x = 2.7 foo(); EOF cat > file2.txt <<EOF double u = 5.7 EOF cat > file3.txt <<EOF goo(42.0); EOF cat > file4.txt <<EOF foo(4); EOF cat > file5.txt <<EOF goo(.42); EOF cat > file6.txt <<EOF goo(.); EOF
Run grep -l ... | xargs grep -l ...
to find the matching files:
grep -Pl '(d+[.]?d*|d*[.]?d+)' file?.txt | xargs grep -Pl '(foo|goo)'
Prints:
file1.txt file3.txt file4.txt file5.txt
Here, grep
uses the following options:
-P
: Use Perl regexes.
-l
: list the file names only, not the matching lines.
The regex has the following parts:
d*
: any digit 0-9, repeated 0 or more times.
d+
: same, repeated 1 or more times.
[.]
: literal dot (.
). Otherwise, without escaping, .
means any character.
SEE ALSO:
-l
--files-with-matches
Suppress normal output; instead print the name of each input file from which output would normally have been printed. The scanning of each file stops on the first match. (
-l
is specified by POSIX.)