Daniel
Daniel

Reputation: 351

Recursively find and open files

I want to search through all subdirectories and files to find files with a specific extension. When I find a file with the extension, I need to open it, find a specific string from within the file and store it within a txt file.

This is what I have so far for finding all of the correct files:

find . -name ".ext" ! -path './ExcludeThis*'

This is what I have for opening the file and getting the part of the file I want and storing it:

LINE=$(head .ext | grep search_string)
SUBSTR=$(echo $LINE | cut -f2 -d '"')
echo $SUBSTR >> results.txt

I am struggling for how to combine the 2 together, I have looked at 'for f in **/*' and then run an if statement in there to see if it matches the .ext and remove the need for find all together but **/* seems to work on directories only and not files.

A break down of any solutions would be very much appreciated too, I am new to shell scripting. Thanks.

Upvotes: 1

Views: 2632

Answers (1)

whoan
whoan

Reputation: 8521

find -name "*.ext" \! -path './ExcludeThis*' -exec head -q '{}' \+ | 
    grep search_string | cut -f2 -d'"' >> results.txt

find explanation

find -name "*.ext" \! -path './ExcludeThis*' -exec head -q '{}' \+

For each file name matched, executes head (with \+, the command line is built by appending each selected file name at the end, so the total number of invocations of the command will be much less than the number of matched files).

Notice I replaced .ext with *.ext (the first way just math a file named exactly .ext), and ! with \! (protection from interpretation by the shell).

The head option -q is necessary because that command prints headers when used with multiple files (due to \+ in this case).

In addition, if no path is given, the default is taken (.). i.e.: find . -name = find -name.


pipeline explanation

<find ... -exec head> | grep search_string | cut -f2 -d'"' >> results.txt
  • While head write the lines (10 by default) for every file in the pipe, grep read them.
  • If grep matches search_string in some of them, write those lines in the next pipe.
  • At the same time, cut take the second fields (delimited by ") of every line and appends them in results.txt

Upvotes: 2

Related Questions