How can I use find command to search string/pattern in a file recursively?


 
Thread Tools Search this Thread
Top Forums Shell Programming and Scripting How can I use find command to search string/pattern in a file recursively?
# 1  
Old 10-03-2016
How can I use find command to search string/pattern in a file recursively?

Hi,

How can I use find command to search string/pattern in a file recursively?
What I tried:
Code:
find . -type f -exec cat {} | grep "make" \;

Output:
Code:
grep: find: ;: No such file or directory
missing argument to `-exec'

And this:
Code:
find . -type f -exec cat {} \; -exec grep "make" {} \;

This print all the contents of files and the matched part of that file. I want to print only the matched part.

I wanted to use find with exec, normally we do
Code:
cat filename | grep "make"

Is it possible to do `cat filename | grep "make"` with find exec ?

Any answer will be highly appreciated.
Thanks in advance.
# 2  
Old 10-03-2016
Hello cola,

If you want to print only the file names which have string makein them then following may help you in same.
Code:
find . -type f -exec grep -l "make" {} \+

In case you want to see the line/record where it has string makein it then following may help you in same too.
Code:
find . -type f -exec grep "make" {} \+

Thanks,
R. Singh
# 3  
Old 10-03-2016
In addition to what R. Singh has already said...

Stop using cat! The grep utility is perfectly capable of opening files by itself and doing it that way is not only MUCH more efficient, it also gets rid of all of your problems. Try:
Code:
find . -type f -exec grep "make" {} \;

or if you want the grep output to let you know which file(s) contain the word you are trying to find; and since you're looking for a fixed string you can make the search much faster with:
Code:
find . -type f -exec grep -F "make" /dev/null {} +

which looks for fixed strings (instead of regular expressions) in large numbers of files with each invocation of grep (instead of one invocation of grep for each file processed).
# 4  
Old 10-03-2016
Quote:
Originally Posted by Don Cragun
In addition to what R. Singh has already said...

Stop using cat! The grep utility is perfectly capable of opening files by itself and doing it that way is not only MUCH more efficient, it also gets rid of all of your problems. Try:
Code:
find . -type f -exec grep "make" {} \;

or if you want the grep output to let you know which file(s) contain the word you are trying to find; and since you're looking for a fixed string you can make the search much faster with:
Code:
find . -type f -exec grep -F "make" /dev/null {} +

which looks for fixed strings (instead of regular expressions) in large numbers of files with each invocation of grep (instead of one invocation of grep for each file processed).
What's the difference between {} \; and {} + or {} \+ ?

Is it possible to call multiple commands with -exec like piping:
Code:
find . -type f -exec onecommand | secondcommand {} \;

What's wrong with using cat?
# 5  
Old 10-03-2016
Quote:
Originally Posted by cola
What's the difference between {} \; and {} + or {} \+ ?
Is it possible to call multiple commands with -exec like piping:
Code:
find . -type f -exec onecommand | secondcommand {} \;

What's wrong with using cat?
Hello cola,

Following are the answers for your queries.
  1. Difference between {} \+and{} \;is {} \+is faster than {} \;.
  2. Yes, it is possible to use multiple exec calls into a single findcommand, it is completely depends on your requirements.
  3. So there is something called UUOC (Useless use of cat), so using catcommand with a command which is able to read Input_file by itself it called UUOC in very short description. Following is an example for same. Let's say we have following Input_file.
Code:
cat  Input_file
abcdef
test test test1
test2 asajndjad
dwjfewygfwkcm wdjcwcnwnc

Now if want to look for string test in above Input_file then example of UUOC is as follows.
Code:
cat Input_file | grep "test"
test test test1
test2 asajndjad

Above will read the Input_file by catcommand then it will push the standard output of this command as standard input to next grepcommand(that's why pipe|is used here) which will then read file and search for string testthen. So point here is unnecessarily we are using catwhen grepitself is capable to read Input_file from itself. So by directly using grephere to read and search Input_file we could save sometime(depending upon you Input_file size) and processes too.

Now following is the example of grepwhich is capable of reading the Input_file by itself and search a string too.
Code:
grep "test"  Input_file
test test test1
test2 asajndjad

I hope this helps you.

Thanks,
R. Singh

Last edited by rbatte1; 10-03-2016 at 09:17 AM.. Reason: Converted to formatted number-list with LIST=i to give roman numerals
# 6  
Old 10-03-2016
Quote:
Originally Posted by Don Cragun
Code:
find . -type f -exec grep -F "make" /dev/null {} +

I guess this is a typo, isn't it? Should be \; in the end, not +
# 7  
Old 10-03-2016
Quote:
Originally Posted by rovf
I guess this is a typo, isn't it? Should be \; in the end, not +
Hi rovf,
No!
Code:
find ... -exec command {} \;

Invokes command once for each file meeting the criteria specified by ..., while:
Code:
find ... -exec command {} +

invokes command once for a group of files meeting the criteria specified by ... with the number of files in the group being determined by the size of the environment passed to command, the length of command, and the length of the pathnames of the files being passed to command.
Quote:
Originally Posted by cola
What's the difference between {} \; and {} + or {} \+ ?

Is it possible to call multiple commands with -exec like piping:
Code:
find . -type f -exec onecommand | secondcommand {} \;

What's wrong with using cat?
The difference between \; and + terminating a find -exec primary is described above.

The command given to a:
Code:
find -exec command {} \;

or:
Code:
find -exec command {} +

primary is something that can be executed by find. The find utility doesn't know how to execute pipelines. You could exec sh -c "pipeline" but the shell's -c operand has to be a single argument so the command you give find won't see the {} (which it will replace with a the name of a found file) as a separate argument, so it might not replace it with the name of a found file. (The standards leave it unspecified whether or not find replaces {} if that string does not appear as a separate argument.)

If you need to use find -exec to run a pipeline (which you DO NOT need to do in this case and doing so would involve running a shell and a cat and a grep when all you need is grep) would be to put the pipeline in a separate shell script such as scriptname containing:
Code:
#!/bin/your_shell
cat "$1" | grep -F 'make'

make it executable with:
Code:
chmod +x scriptname

and move it to some directory in the list of directories in your $PATH environment variable. Then you can execute it with:
Code:
find ... -exec scriptname {} \;

If a small number of files is involved, you might get away with having scriptname contain:
Code:
#!/bin/your_shell
cat "$@" | grep -F /dev/null 'make'

and executing it with:
Code:
find ... -exec scriptname {} +

but if the arguments passed to scriptname along with scriptname and its environment is shorter than the command that scriptname will execute, scriptname may fail with a E2BIG error condition unless you build extra argument loop processing to guarantee that the commands being executed by your script won't fail due to the size of the argument list and environment list your shell will be passing to a member of the exec family of functions to run that stage in your pipeline.

Using:
Code:
grep 'word' "file"

invokes one utility, reads all of the data in file and writes lines in file that contain word while:
Code:
cat "file" | grep 'word'

invokes two utilities, reads all of the data in file, writes all of the data in file reads all of the data in file again and then writes all of the lines in file that contain word. So the useless use of cat creates an unneeded process, forces the system to read and write the entire contents of file an extra unneeded time wasting system memory, wasting I/O bandwidth, and wasting CPU cycles that could be used by other processes to do something useful. Use cat if you need it; DO NOT use cat if you don't need it! Using cat when you don't need it takes longer for you to get the results you want and wastes system resources that you or someone else on your system might need to use to get something done that needs the cycles you are wasting.
This User Gave Thanks to Don Cragun For This Post:
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. Shell Programming and Scripting

Script to find string based on pattern and search for its corresponding rows in column

Experts, Need your support for this awk script. we have only one input file, all these column 1 and column 2 are in same file and have to do lookup for values in one file(column1 and column2) but output we need in another file Need to grep row whose string contains 9K from column 1. When found... (6 Replies)
Discussion started by: as7951
6 Replies

2. UNIX for Beginners Questions & Answers

Search strings from a file in files in a directory recursively; then print the string with a status

Hi All, I hope somebody would be able to help me. I would need to search a string coming from a file, example file.txt: dog cat goat horse fish For every string, I would need to know if there are any files inside a directory(recursively) that contains the string regardless of case.... (9 Replies)
Discussion started by: kokoro
9 Replies

3. UNIX for Advanced & Expert Users

Recursively search the string from a column in no. of files

i have a file named keyword.csv(contains around 8k records) which contains a no. of columns. The 5th column contains all the keywords. I want to recursively search these keywords in all .pl files(around 1k) and display the filename....Afterthat i will use the filename and some of the column from... (3 Replies)
Discussion started by: millan
3 Replies

4. Shell Programming and Scripting

Search for a pattern in a String file and count the occurance of each pattern

I am trying to search a file for a patterns ERR- in a file and return a count for each of the error reported Input file is a free flowing file without any format example of output ERR-00001=5 .... ERR-01010=10 ..... ERR-99999=10 (4 Replies)
Discussion started by: swayam123
4 Replies

5. Shell Programming and Scripting

how to find a pattern from an external file in a directory containing multiple file recursively

Hi, Need your help in this. I have an input file that has multiple enrollment_number, somewhat like 1234567 8901234 9856321 6732187 7623465 Now i have to search and delete these enrollment_number recursively from all the files that are within multiple sub-directories of a... (10 Replies)
Discussion started by: mukulverma2408
10 Replies

6. Shell Programming and Scripting

Awk search for string pattern in delimited file

I've got a semicolon delimited file. I would like to search for fields that match a pattern, and not hardcoded eg "mth". *th=something If the delimited field fulfills this condition, eg. mth=value I would like to print out both key and value for some number comparison. eg. if value > "12"... (5 Replies)
Discussion started by: alienated
5 Replies

7. Shell Programming and Scripting

Using find command to search a pattern in group of files

Hi i am having a group of *.csh files under parent directory. Now i want to search a particular pattern in these group of *.csh files(suppose i need to search a pattern ABC - proj ). Can anyone please tell me how to do it using find command. Thanks in advance sarbjit (4 Replies)
Discussion started by: sarbjit
4 Replies

8. Shell Programming and Scripting

find and replace a search string recursively in files

Hi , I have a directory structure as dir and subdirectories and files under it and so on.now I need to find the files which contain the search string under every dir and subdir and replace . my search string is like searchstring=/a/b string to be replaced=/a/c/b please help. ... (7 Replies)
Discussion started by: mohanpadamata
7 Replies

9. UNIX for Dummies Questions & Answers

String search - Command to find second occurance

Hi, I am new to Unix world. Is there any command which can directly return the second occurance of a particular string in a file? Basically, I want to read the contents of the file from the second occurance of a particualr string. Can be implemented using a loop, but am just wondering if there... (5 Replies)
Discussion started by: saurabhsinha23
5 Replies

10. Shell Programming and Scripting

Search Mulitiple String pattern in a file

Hi, I need to search for a multiple string pattern(5 key words) in a file(similar to a flat file) ,and i need to store the output in a another file . In that file we may have mutiple occurrences of the key words.and i need only the unique. kindly help out. Thanks, Mohana Krishnan (2 Replies)
Discussion started by: krishnan_6015@y
2 Replies
Login or Register to Ask a Question