How to Find the File Which Contains a Specific Text in Linux

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



Leave a reply



Submit