Find all files containing a specific text (string) on Linux?

10.9m Views Asked by At

How do I find all files containing a specific string of text within their file contents?

The following doesn't work. It seems to display every single file in the system.

find / -type f -exec grep -H 'text-to-find-here' {} \;
57

There are 57 best solutions below

5
On BEST ANSWER

Do the following:

grep -Rnw '/path/to/somewhere/' -e 'pattern'
  • -r or -R is recursive ; use -R to search entirely
  • -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/search/' -e "pattern"
    

This works very well for me, to achieve almost the same purpose like yours.

For more options, see man grep.

0
On

Use:

grep -c Your_Pattern *

This will report how many copies of your pattern are there in each of the files in the current directory.

0
On

I wrote a Python script which does something similar. This is how one should use this script.

./sniff.py path pattern_to_search [file_pattern]

The first argument, path, is the directory in which we will search recursively. The second argument, pattern_to_search, is a regular expression which we want to search in a file. We use the regular expression format defined in the Python re library. In this script, the . also matches newline.

The third argument, file_pattern, is optional. This is another regular expression which works on a filename. Only those files which matches this regular expression will be considered.

For example, if I want to search Python files with the extension py containing Pool( followed by word Adaptor, I do the following,

./sniff.py . "Pool(.*?Adaptor"  .*py
./Demos/snippets/cubeMeshSigNeur.py:146 
./Demos/snippets/testSigNeur.py:259 
./python/moose/multiscale/core/mumbl.py:206 
./Demos/snippets/multiComptSigNeur.py:268 

And voila, it generates the path of matched files and line number at which the match was found. If more than one match was found, then each line number will be appended to the filename.

1
On

Try:

find . -name "*.txt" | xargs grep -i "text_pattern"
2
On

Try this:

find . | xargs grep 'word' -sl
1
On
grep "text-to-find-here" file_name

or

grep "text-to-find-here" directory_path/*

If you want to search the current directory:

grep "text-to-find-here" *
3
On

To search for the string and output just that line with the search string:

for i in $(find /path/of/target/directory -type f); do grep -i "the string to look for" "$i"; done

e.g.:

for i in $(find /usr/share/applications -type f); \
do grep -i "web browser" "$i"; done

To display filename containing the search string:

for i in $(find /path/of/target/directory -type f); do if grep -i "the string to look for" "$i" > /dev/null; then echo "$i"; fi; done;

e.g.:

for i in $(find /usr/share/applications -type f); \
do if grep -i "web browser" "$i" > /dev/null; then echo "$i"; \
fi; done;
6
On
grep -insr "pattern" *
  • i: Ignore case distinctions in both the PATTERN and the input files.
  • n: Prefix each line of output with the 1-based line number within its input file.
  • s: Suppress error messages about nonexistent or unreadable files.
  • r: Read all files under each directory, recursively.
0
On

I think it is worth mentioning how you can find:

All files containing at least one text, among a big set of texts:

grep -rlf ../patternsFile.txt .

Output:

./file1
./file2
./file4

The above, grouped by each text:

cat ../patternsFile.txt | xargs -I{} sh -c "echo {}; grep -rl \"{}\" ."

Output:

pattern1
./file1
./file2
pattern2
./file1
./file4
pattern3
./file1
./file2
./file4

Note that in order not to match patternsFile.txt itself, you need to add it one directory up (as shown in the above examples).

2
On

This grep command will give you a precise result when you are searching for specific text on Linux -

grep -inRsH "Text to be searched" /path/to/dir (it can be '.')

  • i stands for ignore case distinctions

  • R stands for recursive and it also include symlinks. It is better to use 'R' instead of 'r'

  • n stands for "it will print line number".

  • s stands for "suppress error messages"

  • H stands for "it will print the file name for each match"

2
On

Recursive and case insensitive grep with line numbers:

grep -inr "Text" folder/to/be/searched/
6
On
grep -lrnw '/root/Desktop/ipozal' -e 'geolocation'

For example:

  • my folder name is "ipozal"
  • it placed on "/root/Desktop"
  • I want to find this text on all files in it "geolocation"
1
On

I tried the grep command below. It helps searching contents within my repository at /etc/yum.repos.d.

grep -Ril -e 'texttoSearch' /etc/yum.repos.d
2
On

find with xargs is preferred when there are many potential matches to sift through. It runs more slowly than other options, but it always works. As some have discovered,xargs does not handle files with embedded spaces by default. You can overcome this by specifying the -d option.

Here is @RobEarl's answer, enhanced so it handles files with spaces:

find / -type f | xargs -d '\n' grep 'text-to-find-here'

Here is @venkat's answer, similarly enhanced:

find . -name "*.txt" | xargs -d '\n' grep -i "text_pattern"

Here is @Gert van Biljon's answer, similarly enhanced:

find . -type f -name "*.*" -print0 | xargs -d '\n' --null grep --with-filename --line-number --no-messages --color --ignore-case "searthtext"

Here is @LetalProgrammer's answer, similarly enhanced:

alias ffind find / -type f | xargs -d '\n' grep

Here is @Tayab Hussain's answer, similarly enhanced:

find . | xargs -d '\n' grep 'word' -sl
3
On

If you are in a Git repository, you can use:

git grep something
4
On

List of file names containing a given text

First of all, I believe you have used -H instead of -l. Also you can try adding the text inside quotes followed by {} \.

find / -type f -exec grep -l "text-to-find-here" {} \; 

Example

Let's say you are searching for files containing specific text "Apache License" inside your directory. It will display results somewhat similar to below (output will be different based on your directory content).

bash-4.1$ find . -type f -exec grep -l "Apache License" {} \; 
./net/java/jvnet-parent/5/jvnet-parent-5.pom
./commons-cli/commons-cli/1.3.1/commons-cli-1.3.1.pom
./io/swagger/swagger-project/1.5.10/swagger-project-1.5.10.pom
./io/netty/netty-transport/4.1.7.Final/netty-transport-4.1.7.Final.pom
./commons-codec/commons-codec/1.9/commons-codec-1.9.pom
./commons-io/commons-io/2.4/commons-io-2.4.pom
bash-4.1$ 

Remove case sensitiveness

Even if you are not use about the case like "text" vs "TEXT", you can use the -i switch to ignore case. You can read further details here.

2
On

If your grep doesn't support recursive search, you can combine find with xargs:

find / -type f | xargs grep 'text-to-find-here'

I find this easier to remember than the format for find -exec.

This will output the filename and the content of the matched line, e.g.

/home/rob/file:text-to-find-here

Optional flags you may want to add to grep:

  • -i - case insensitive search
  • -l - only output the filename where the match was found
  • -h - only output the line which matched (not the filename)
2
On

Here are the several list of commands that can be used to search file.

grep "text string to search” directory-path

grep [option] "text string to search” directory-path

grep -r "text string to search” directory-path

grep -r -H "text string to search” directory-path

egrep -R "word-1|word-2” directory-path

egrep -w -R "word-1|word-2” directory-path
0
On

As Peter in the previous answer mentioned, all previous answers suggest grep and find.

But there is a more sophisticated way using Gnome Commander with a perfect GUI and with tons of options since 2001, and finding files is just one of them. It is a free utility as well, proven by time.

1
On

My use case was to find Python code I had written way back that wrote jsonlines a particular way. I knew that jsonl would be part of the function name and to_json would appear in the body, but not much else.

Despite 50 answers, finding more than one string in the same file (whether or not in the same line) hasn't been answered.

The -q in grep is for quiet. Nothing is printed, only the return value is set. Thus the -print at the end. Each -exec only runs if the previous one succeeded. So if you have many files it pays to think about patterns that will eliminate files you aren't interested in.

find . -type f -name "*.py" \
  -exec grep -q -e 'to_json' {} \; \
  -exec grep -q -e 'def\s.*jsonl' {} \; \
  -print
2
On

There is the ack tool that would do exactly what you are looking for:

ack -i search_string folder_path/*

You may ignore -i for case sensitive search.

8
On

Try this

find . -type f -name some_file_name.xml -exec grep -H PUT_YOUR_STRING_HERE {} \;
0
On

How do I find all files containing specific text on Linux? (...)

I came across this solution twice:

find / -type f -exec grep -H 'text-to-find-here' {} \;


If using find like in your example, better add -s (--no-messages) to grep, and 2>/dev/null at the end of the command to avoid lots of Permission denied messages issued by grep and find:

find / -type f -exec grep -sH 'text-to-find-here' {} \; 2>/dev/null

find is the standard tool for searching files - combined with grep when looking for specific text - on Unix-like platforms. The find command is often combined with xargs, by the way.

Faster and easier tools exist for the same purpose - see below. Better try them, provided they're available on your platform, of course:

Faster and easier alternatives

RipGrep - fastest search tool around:

rg 'text-to-find-here' / -l

The Silver Searcher:

ag 'text-to-find-here' / -l

ack:

ack 'text-to-find-here' / -l

Note: You can add 2>/dev/null to these commands as well, to hide many error messages.


Warning: unless you really can't avoid it, don't search from '/' (the root directory) to avoid a long and inefficient search! So in the examples above, you'd better replace '/' by a sub-directory name, e.g. "/home" depending where you actually want to search...

2
On

If you strictly want to use find then use find + grep:

find /path/to/somewhere/ -type f -exec grep -nw 'textPattern' {} \;

Steps:

  1. Use find to search files,
  2. Execute grep on all of them.

This gives you the power of find to find files.

  • Use -name Pattern if you want to grep only certain files:

find /path/to/somewhere/ -type f -name \*.cpp -exec grep -nw 'textPattern' {} \;

You can use different options of find to improve your file search.

1
On

grep can be used even if we're not looking for a string.

Simply running,

grep -RIl "" .

will print out the path to all text files, i.e. those containing only printable characters.

2
On

You can use ripgrep which will respect the default project's .gitignore file.

$ rg fast README.md
75:  faster than both. (N.B. It is not, strictly speaking, a "drop-in" replacement
88:  color and full Unicode support. Unlike GNU grep, ripgrep stays fast while
119:### Is it really faster than everything else?
124:Summarizing, ripgrep is `fast` because:
129:  optimizations to make searching very fast.

where fast keyword is highlighted in the terminal.

To suppress Permission denied errors:

$ rg -i rustacean 2> /dev/null

Which will redirect the standard error (stderr) output to /dev/null.

0
On

Try this command. Which will give you the files containing the pattern you entered.

sudo grep -inr "your-pattern" /

Here: i - Ignore case distinctions, so that characters that differ only in case match each other.

n - Make sure that the first character of actual line content lies on a tab stop, so that the alignment of tabs looks normal.

r - Read all files under each directory, recursively, following symbolic links only if they are on the command line. Note that if no file operand is given, grep searches the working directory.

1
On

See also The Platinium Searcher, which is similar to The Silver Searcher and it's written in Go.

Example:

pt -e 'text to search'
0
On

If you have a set of files that you will always be checking you can alias their paths, for example:

alias fd='find . -type f -regex ".*\.\(inc\|info\|module\|php\|test\|install\|uninstall\)"'

Then you can simply filter the list like this:

grep -U -l $'\015' $(fd)

Which filters out the list fd to files that contain the CR pattern.

I find that aliasing the files that I am interested in helps me create easier scripts then always trying to remember how to get all those files. The recursive stuff works as well but sooner or later you are going to have to contend with weeding out specific file types. Which is is why I just find all the file types I'm interested in to begin with.

2
On

Expanding the grep a bit to give more information in the output, for example, to get the line number in the file where the text is can be done as follows:

find . -type f -name "*.*" -print0 | xargs --null grep --with-filename --line-number --no-messages --color --ignore-case "searthtext"

And if you have an idea what the file type is you can narrow your search down by specifying file type extensions to search for, in this case .pas OR .dfm files:

find . -type f \( -name "*.pas" -o -name "*.dfm" \) -print0 | xargs --null grep --with-filename --line-number --no-messages --color --ignore-case "searchtext"

Short explanation of the options:

  1. . in the find specifies from the current directory.
  2. -name "*.*" : for all files ( -name "*.pas" -o -name "*.dfm" ) : Only the *.pas OR *.dfm files, OR specified with -o
  3. -type f specifies that you are looking for files
  4. -print0 and --null on the other side of the | (pipe) are the crucial ones, passing the filename from the find to the grep embedded in the xargs, allowing for the passing of filenames WITH spaces in the filenames, allowing grep to treat the path and filename as one string, and not break it up on each space.
3
On

The below command will work fine for this approach:

find ./ -name "file_pattern_name"  -exec grep -r "pattern" {} \;
0
On

Go to the directory. For search, then search your text by -> grep -r "yoursearchtext"

Now you should see all files which has matching text.

Then go to file → less fileName

Then read the file's full text → Shift + G

Then search the text in the file → ?+yousearchText

Then search all matching case → Ctrl + N

3
On

grep is your good friend to achieve this.

grep -r <text_fo_find> <directory>

If you don't care about the case of the text to find, then use:

grep -ir <text_to_find> <directory>
1
On

There's a new utility called The Silversearcher

sudo apt install silversearcher-ag

It works closely with Git and other VCS. So you won't get anything in a .git or another directory.

You can simply use

ag "Search query"

And it will do the task for you!

4
On

You can use ack. It is like grep for source code. You can scan your entire file system with it.

Just do:

ack 'text-to-find-here'

In your root directory.

You can also use regular expressions, specify the filetype, etc.


UPDATE

I just discovered The Silver Searcher, which is like ack but 3-5x faster than it and even ignores patterns from a .gitignore file.

4
On

Use grep -ilR:

grep -Ril "text-to-find-here" /
  • i stands for ignore case (optional in your case).
  • R stands for recursive.
  • l stands for "show the file name, not the result itself".
  • / stands for starting at the root of your machine.
0
On

Silver Searcher is a terrific tool, but ripgrep may be even better.

It works on Linux, Mac and Windows, and was written up on Hacker News a couple of months ago (this has a link to Andrew Gallant's Blog which has a GitHub link):

Ripgrep – A new command line search tool

2
On

You can use below command as you don't want file name but you want to search from all the files. Here are i am capturing "TEXT" form All the log files making sure that file name is not printed

grep -e TEXT *.log | cut -d' ' --complement -s -f1

grep with -e option is quite quick compared to other option as it is for PATTERN match

0
On

You can edit and use like this:

find /your-path -type f -exec grep -l 'text-to-find-here' {} +
0
On

GUI Search Alternative - For Desktop Use:

- As the question is not precisely asking for commands

Searchmonkey: Advanced file search tool without having to index your system using regular expressions. Graphical equivalent to find/grep. Available for Linux (Gnome/KDE/Java) and Windows (Java) - open source GPL v3

Features:

  • Advanced Regular Expressions
  • Results shown in-context
  • Search containing text
  • Panel to display line containing text
  • New 2018 updates
  • etc.

Download - Links:

.

Screen-shot:

Enter image description here

2
On

After checking the alternatives for a desktop, I wrote an open-source GUI program for full text search. It's blazing fast in comparison with grep flavors.

You can check it at Missing Linux GUI app to full-text search files. It can search for both content and file names in a intuitive search string, so you can look for "license mit *.md" and get few false positives ;)

10
On

Use pwd to search from any directory you are in, recursing downward

grep -rnw `pwd` -e "pattern"

Depending on the version of grep you are using, you can omit pwd. In newer versions . seems to be the default case for grep if no directory is given.

Thus:

grep -rnw -e "pattern"

or

grep -rnw "pattern"

will do the same thing as above!

2
On

I am fascinated by how simple grep makes it with 'rl':

grep -rl 'pattern_to_find' /path/where/to/find

-r to recursively find a file / directory inside directories..
-l to list files matching the 'pattern'

Use '-r' without 'l' to see the file names followed by text in which the pattern is found!

grep -r 'pattern_to_find' /path/where/to/find

It works just perfect...

0
On
find /path -type f -exec grep -l "string" {} \;

Explanation from comments

find is a command that lets you find files and other objects like directories and links in subdirectories of a given path. If you don't specify a mask that filesnames should meet, it enumerates all directory objects.

-type f specifies that it should proceed only files, not directories etc.
-exec grep specifies that for every found file, it should run grep command, passing its filename as an argument to it, by replacing {} with the filename
1
On

You can use:

grep -r "string to be searched" /path/to/dir

The r stands for recursive and so will search in the path specified and also its sub-directories. This will tell you the file name as well as print out the line in the file where the string appears.

Or a command similar to the one you are trying (example: ) for searching in all javascript files (*.js):

find . -name '*.js' -exec grep -i 'string to search for' {} \; -print

This will print the lines in the files where the text appears, but it does not print the file name.

In addition to this command, we can write this too: grep -rn "String to search" /path/to/directory/or/file -r: recursive search n: line number will be shown for matches

1
On

grep (GNU or BSD)

You can use grep tool to search recursively the current folder, like:

grep -r "class foo" .

Note: -r - Recursively search subdirectories.

You can also use globbing syntax to search within specific files such as:

grep "class foo" **/*.c

Note: By using globbing option (**), it scans all the files recursively with specific extension or pattern. To enable this syntax, run: shopt -s globstar. You may also use **/*.* for all files (excluding hidden and without extension) or any other pattern.

If you've the error that your argument is too long, consider narrowing down your search, or use find syntax instead such as:

find . -name "*.php" -execdir grep -nH --color=auto foo {} ';'

Alternatively, use ripgrep.

ripgrep

If you're working on larger projects or big files, you should use ripgrep instead, like:

rg "class foo" .

Checkout the docs, installation steps or source code on the GitHub project page.

It's much quicker than any other tool like GNU/BSD grep, ucg, ag, sift, ack, pt or similar, since it is built on top of Rust's regex engine which uses finite automata, SIMD and aggressive literal optimizations to make searching very fast.

It supports ignore patterns specified in .gitignore files, so a single file path can be matched against multiple glob patterns simultaneously.


You can use common parameters such as:

  • -i - Insensitive searching.
  • -I - Ignore the binary files.
  • -w - Search for the whole words (in the opposite of partial word matching).
  • -n - Show the line of your match.
  • -C/--context (e.g. -C5) - Increases context, so you see the surrounding code.
  • --color=auto - Mark up the matching text.
  • -H - Displays filename where the text is found.
  • -c - Displays count of matching lines. Can be combined with -H.
3
On

Try:

find / -type f -exec grep -H 'text-to-find-here' {} \;

which will search all file systems, because / is the root folder.

For home folder use:

find ~/ -type f -exec grep -H 'text-to-find-here' {} \;

For current folder use:

find ./ -type f -exec grep -H 'text-to-find-here' {} \;
0
On

I'm trying to find a way to scan my entire Linux system for all files containing a specific string of text. ... Is this close to the proper way to do it? If not, how should I? ... This ability to find text strings in files would be extraordinarily useful for some programming projects I'm doing.

While you should never replace (or alias) a system command with a different program, due to risk of mysterious breakage of scripts or other utilities, if you are running a text search manually or from your own scripts or programs you should consider the fastest suitable program when searching a large number of files a number of times. Ten minutes to half an hour time spent installing and familiarizing yourself with a better utility can be recovered after a few uses for the use-case you described.

A webpage offering a "Feature comparison of ack, ag, git-grep, GNU grep and ripgrep" can assist you to decide which program offers the features you need.

  • Andrew Gallant's Blog claims: "ripgrep is faster than {grep, ag, git grep, ucg, pt, sift}" (a claim shared by some of the others, this is why a feature comparison is helpful). Of particular interest is his section on regex implementations and pitfalls.

    The following command searches all files, including hidden and executable:

    $ rg -uuu foobar

  • The Silver Searcher (ag) claims it is 5-10x faster than Ack. This program is suggested in some other answers. The GitHub doesn't appear as recent as ripgrep's and there are noticably more commits and branches with fewer releases, it's hard to draw an absolute claim based on those stats. The short version: ripgrep is faster, but there's a tiny learning curve to not get caught by the differences.

  • So what could be next, you guessed it, the platinum searcher. The claims are: it searches code about 3–5× faster than ack, but its speed is equal to the silver searcher. It's written in GoLang and searches UTF-8, EUC-JP and Shift_JIS files; if that's of greater interest. The GitHub is neither particularly recent or active. GoLang itself has a fast and robust regex, but the platinum searcher would be better recommended if it had a better user interest.

For a combination of speed and power indexed query languages such as ElasticSearch or Solr can be a long term investment that pays off, but not if you want a quick and simple replacement for grep. OTOH both have an API which can be called from any program you write, adding powerful searches to your program.

While it's possible to spawn an external program, execute a search, intercept its output and process it, calling an API is the way to go for power and performance.

This question was protected Aug 6 '15 at 19:34 with this caution:
  We're looking for long answers that provide some explanation and context. Don't just give a one-line answer; explain why your answer is right, ideally with citations.

While some answers suggest alternative ways to accomplish a search they don't explain why other than it's "free", "faster", "more sophisticated", "tons of features", etc. Don't try to sell it, just tell us "why your answer is right". I've attempted to teach how to choose what's best for the user, and why. This is why I offer yet another answer, when there are already so many. Otherwise I'd agree that there are already quite a few answers; I hope I've brought a lot new to the table.

2
On

You can also use awk:

awk '/^(pattern)/{print}' /path/to/find/*

pattern is the string you want to match in the files.

1
On

Use:

grep -Erni + "text you wanna search"

The command will search recursively in all files and directories of the current directory and print the result.

Note: if your grep output isn't colored, you can change it by using the grep='grep --color=always' alias in your shell source file.

4
On

Try this:

find / -type f -name "*" -exec grep -il "String_to_search" {} \;

Or

for i in /*;do grep -Ril "String_to_search" $i;done 2> /dev/null
2
On

Avoid the hassle and install ack-grep. It eliminates a lot of permission and quotation issues.

apt-get install ack-grep

Then go to the directory you want to search and run the command below

cd /
ack-grep "find my keyword"
2
On

You can use the following commands to find particular text from a file:

cat file | grep 'abc' | cut -d':' -f2
0
On

A simple find can work handy. alias it in your ~/.bashrc file:

alias ffind find / -type f | xargs grep

Start a new terminal and issue:

ffind 'text-to-find-here'
1
On

All previous answers suggest grep and find. But there is another way: Use Midnight Commander

It is a free utility (30 years old, proven by time) which is visual without being GUI. It has tons of functions, and finding files is just one of them.

0
On

Your command is correct. You just need to add -l to grep:

find / -type f -exec grep -l 'text-to-find-here' {} \;
3
On

Kindly customize the below command according to demand and find any string recursively from files.

grep -i hack $(find /etc/ -type f)