How to find all files containing specific text (string) on Linux?
Do the following:
grep -rnw '/path/to/somewhere/' -e 'pattern'
-r
or-R
is recursive,-n
is line number, and-w
stands for match the whole word.-l
(lower-case L) can be added to just give the file name of matching files.-e
is the pattern used during the search
Along with these, --exclude
, --include
, --exclude-dir
flags could be used for efficient searching:
- This will only search through those files which have .c or .h extensions:
grep --include=\*.{c,h} -rnw '/path/to/somewhere/' -e "pattern"
- This will exclude searching all the files ending with .o extension:
grep --exclude=\*.o -rnw '/path/to/somewhere/' -e "pattern"
- For directories it's possible to exclude one or more directories using the
--exclude-dir
parameter. For example, this will exclude the dirs dir1/, dir2/ and all of them matching *.dst/:
grep --exclude-dir={dir1,dir2,*.dst} -rnw '/path/to/somewhere/' -e "pattern"
This works very well for me, to achieve almost the same purpose like yours.
For more options, see man grep
.
How to find all files containing specific text (string) on Linux?
Do the following:
grep -rnw '/path/to/somewhere/' -e 'pattern'
-r
or-R
is recursive,-n
is line number, and-w
stands for match the whole word.-l
(lower-case L) can be added to just give the file name of matching files.-e
is the pattern used during the search
Along with these, --exclude
, --include
, --exclude-dir
flags could be used for efficient searching:
- This will only search through those files which have .c or .h extensions:
grep --include=\*.{c,h} -rnw '/path/to/somewhere/' -e "pattern"
- This will exclude searching all the files ending with .o extension:
grep --exclude=\*.o -rnw '/path/to/somewhere/' -e "pattern"
- For directories it's possible to exclude one or more directories using the
--exclude-dir
parameter. For example, this will exclude the dirs dir1/, dir2/ and all of them matching *.dst/:
grep --exclude-dir={dir1,dir2,*.dst} -rnw '/path/to/somewhere/' -e "pattern"
This works very well for me, to achieve almost the same purpose like yours.
For more options, see man grep
.
Find all files with name containing string
Use find
:
find . -maxdepth 1 -name "*string*" -print
It will find all files in the current directory (delete maxdepth 1
if you want it recursive) containing "string" and will print it on the screen.
If you want to avoid file containing ':', you can type:
find . -maxdepth 1 -name "*string*" ! -name "*:*" -print
If you want to use grep
(but I think it's not necessary as far as you don't want to check file content) you can use:
ls | grep touch
But, I repeat, find
is a better and cleaner solution for your task.
grep -rnw: search for a string in all files
explainshell helpfully explains your command, and gives an excerpt from man grep
:
-w, --word-regexp
Select only those lines containing matches that form whole words.
So just remove -w
since that explicitly does what you don't want:
grep -rn '/path/to/somewhere/' -e "pattern"
Find Files Containing Certain String and Copy To Directory Using Linux
Edit: After clearing things up (see comment)...
cp *Qtr_1_results* /data/jobs/file/obj1
What you're doing is just greping for nothing. With ;
you end the command and cp
prints the error message because you only provide the source, not the destination.
What you want to do is the following. First you want to grep for the filename, not the string (which you didn't provide).
grep -l the_string_you_are_looking_for *Qtr_1_results*
The -l
option gives you the filename, instead of the line where the_string_you_are_looking_for
is found. In this case grep
will search in all files where the filename contains Qtr_1_results
.
Then you want send the output of grep
to a while
loop to process it. You do this with a pipe (|
). The semicolon ;
just ends lines.
grep -l the_string_you_are_looking_for *Qtr_1_results* | while read -r filename; do cp $filename /path/to/your/destination/folder; done
In the while
loop read -r
will put the output of grep
into the variable filename
. When you assing a value to a variable you just write the name of the variable. When you want to have the value of the variable, you put a $
in front of it.
Get files which contains a specific text using Linux
May be the question was confusing, i hope its clear now, the patten should match the content not the filename !
Your question was not clear, and in the original answer I have shown how to find filenames matching a pattern. If you only want to search for files with content matching a pattern, it's as simple as
grep 'pattern' directory/*
(the shell globbing is used).
You can still use find
to filter out the files before passing to grep
:
find 'directory' -maxdepth 1 -mindepth 1 -type f \
-exec grep --with-filename 'pattern' {} +
Original Answer
Grep is not appropriate tool for searching for filenames, since you need to generate a list of files before passing to Grep. Even if you get the desired results with a command like ls | grep pattern
, you will have to append another pipe in order to process the files (I guess, you will most likely need to process them somehow, sooner or later).
Use find
instead, as it has its own powerful pattern matching features.
Example:
find 'directory' -maxdepth 1 -mindepth 1 -regex '.*pattern'
Use -iregex
for case insensitive version of -regex
. Also read about -name
, -iname
, -path
, and -ipath
options.
It is possible to run a command (or script) for the files being processed with -exec
action, e.g.:
find 'directory' -maxdepth 1 -mindepth 1 -type f \
-regex '.*pattern' -exec sed -i.bak -r 's/\btwo\b/2/g' {} +
How do I find all files containing specific text on Linux but not in subdirectories?
You can use:
grep 'text' /search/path/*
# ^
The *
will expand to all the elements in the directory and the absence of -R
will avoid going deeper into subdirectories.
The drawback of this approach is that it will exclude the hidden files, since .files
do not expand with *
alone. If you also want to grep those, you can use:
grep 'text' /search/path/{*,.*}
# \____/
This way you will get all elements matching *
and .*
which is everything.
Finally, if you do not want to get the error message:
search/path/ Is a directory
You can redirect it to /dev/null as follows:
grep 'text' /search/path/{*,.*} 2>/dev/null
# \_________/
How to check if a file contains a specific string using Bash
if grep -q SomeString "$File"; then
Some Actions # SomeString was found
fi
You don't need [[ ]]
here. Just run the command directly. Add -q
option when you don't need the string displayed when it was found.
The grep
command returns 0 or 1 in the exit code depending on
the result of search. 0 if something was found; 1 otherwise.
$ echo hello | grep hi ; echo $?
1
$ echo hello | grep he ; echo $?
hello
0
$ echo hello | grep -q he ; echo $?
0
You can specify commands as an condition of if
. If the command returns 0 in its exitcode that means that the condition is true; otherwise false.
$ if /bin/true; then echo that is true; fi
that is true
$ if /bin/false; then echo that is true; fi
$
As you can see you run here the programs directly. No additional []
or [[]]
.
Related Topics
Phusion Passenger Nginx Module Installer V3.0.17 Issue on Debian 6.0.5 Amd64 Due to Broken Package
How to Get Around the Linux "Too Many Arguments" Limit
Combine Two CSV Files Based on Common Column Using Awk or Sed
Where Is $Path Set? Specifically Where Is My MAC Port Path Being Set
Automating Killall Then Killall Level 9
Delete Folder That Contain Subfolders and Files on Linux
Bash: Checking If Files Are Duplicates Within a Directory
Remove Left and Right Square Brackets Using Sed/Bash
How to Know the Current Quarter with Date
Determine Os from a Single Command Line Operation
Bash/Linux Sort by 3Rd Column Using Custom Field Seperator
Why Would the Elf Header of a Shared Library Specify Linux as the Osabi
How Come _Exit(0) (Exiting by Syscall) Prevents Me from Receiving Any Stdout Content
Overhead of Supporting Floating Point Arithmetic Inside the Linux Kernel
Can Libpcap Reassemble Tcp Segments
Interacting with Files from Multiple Directories via Bash Script
How to Split Flv File by Size Using Ffmpeg or Mencoder or Smth Else