I would like to (recursively) find all files with "ABC" in their file name, which also contain "XYZ" in the file. I tried:
find . -name "*ABC*" | grep -R 'XYZ'
but its not giving the correct output.
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It only takes a minute to sign up.
Sign up to join this communityThat's because grep
can't read file names to search through from standard input. What you're doing is printing file names that contain XYZ
. Use find
's -exec
option instead:
find . -name "*ABC*" -exec grep -H 'XYZ' {} +
From man find
:
-exec command ;
Execute command; true if 0 status is returned. All following
arguments to find are taken to be arguments to the command until
an argument consisting of `;' is encountered. The string `{}'
is replaced by the current file name being processed everywhere
it occurs in the arguments to the command, not just in arguments
where it is alone, as in some versions of find.
[...]
-exec command {} +
This variant of the -exec action runs the specified command on
the selected files, but the command line is built by appending
each selected file name at the end; the total number of invoca‐
tions of the command will be much less than the number of
matched files. The command line is built in much the same way
that xargs builds its command lines. Only one instance of `{}'
is allowed within the command. The command is executed in the
starting directory.
If you don't need the actual matching lines but only the list of file names containing at least one occurrence of the string, use this instead:
find . -name "*ABC*" -exec grep -l 'XYZ' {} +
I find the following command the simplest way:
grep -R --include="*ABC*" XYZ
or add -i
to search case insensitive:
grep -i -R --include="*ABC*" XYZ
… | grep -R 'XYZ'
does not make sense. On one hand, -R 'XYZ'
means to recursively act on the XYZ
directory. On the other hand, … | grep 'XYZ'
means to look for the pattern XYZ
in grep
's standard input.\
On Mac OS X or BSD, grep
will treat XYZ
as a pattern, and complain:
$ echo XYZ | grep -R 'XYZ'
grep: warning: recursive search of stdin
(standard input):XYZ
GNU grep
will not complain. Rather, it treats XYZ
as a pattern, ignores its standard input, and recursively searches starting from the current directory.
What you meant to do was probably
find . -name "*ABC*" | xargs grep -l 'XYZ'
… which is similar to
grep -l 'XYZ' $(find . -name "*ABC*")
… both of which tell grep
to look for XYZ
in the matching file names.
Note, however, that any whitespace in the filenames will cause those two commands to break. You can use xargs
safely by using NUL as the delimiter:
find . -name "*ABC*" -print0 | xargs -0 grep -l 'XYZ'
But @terdon's solution using find … -exec grep -l 'XYZ' '{}' +
is simpler and better.
Linux Commend : ll -iR | grep "filename"
ex: Bookname.txt then use ll -iR | grep "Bookname" or ll -iR | grep "name" or ll -iR | grep "Book"
we can search with part of the file name.
This will list all the file names matching from the current and sub folders
find
as shown in some of the other answers.