How to Recursively Grep All Directories and Subdirectories

How do I recursively grep all directories and subdirectories?

grep -r "texthere" .

The first parameter represents the regular expression to search for, while the second one represents the directory that should be searched. In this case, . means the current directory.

Note: This works for GNU grep, and on some platforms like Solaris you must specifically use GNU grep as opposed to legacy implementation. For Solaris this is the ggrep command.

How to grep recursively and ignore subdirectories of subdirectories?

This will exclude the (sub)directories with names idc and otherStuffIdc.

 grep -r pattern --exclude-dir=idc,otherStuffIdc

Using grep to recursively search through subdirectories for specific keyword inside specific filename

Continuing from my comment, you can use find to locate the file vsim.log if you do not know its exact location and then use the -execdir option to find to grep the file for the term Elapsed time, e.g.

find path -type f -name "vsim.log" -execdir grep -H 'Elapsed time' '{}' +

That will return the filename along with the matched text which you can simply parse to isolate the filename if desired. You can process all files that match if you anticipate more than one by feeding the results of the find command into a while read -r loop, e.g.

while read -r match; do
# process "$match" as desired
echo "Term 'Elapsed time' found in file ${match%:*}"
done < <(find path -type f -name "vsim.log" -execdir grep -H 'Elapsed time' '{}' +)

Where:

  • find is the swiss-army knife for finding files on your system

  • path can be any relative or absolute path to search (e.g. $HOME or /home/dorojevets) to search all files in your home directory

  • the option -type f tells find to only locate files (see man find for link handling)

  • the option -name "foo" tell find to only locate files named foo (wildcards allowed)

  • the -exec and -execdir options allow you to execute the command that follows on each file (represented by '{}')

  • the grep -H 'Elapsed time' '{}' being the command to execute on each filename

  • the + being what tells find it has reached the end of the command (\; used with -exec)

  • finally, the ${match%:*} parameter expansion on the variable $match is used to parse the filename from filename:Elapsed time returned by grep -H (the %:* simply being used to trim everything to the first : from the right of $match)

Give that a try and compare the execution time to a recursive grep of the file tree. What you may be missing in this discussion, is that you use find if you know some part of the filename (or file mod time, or set of permissions, etc) that contains the information you need. It can search millions of files in a file tree vastly quicker than you can recursively grep every single file. If you have no clue what file may contain the needed info -- then use grep and just wait...

How do I grep recursively in files with a certain extension?

find allows you to run a program on each file it finds using the -exec option:

find -name '*.out' -exec grep -H pattern {} \;

{} indicates the file name, and ; tells find that that's the end of the arguments to grep. -H tells grep to always print the file name, which it normally does only when there are multiple files to process.

How can I recursively find all files in current and subfolders based on wildcard matching?

Use find:

find . -name "foo*"

find needs a starting point, so the . (dot) points to the current directory.

How do I recursively grep files in multiple folders? I'm unable to pipe the recursive cat output

You can use awk to mathematically add all scores and print sum:

cd files # parent directory of set1, set2, set3, set4

awk -F= '$1 == "score" { sum += $2 } END { print sum }' */result.txt
251

recursively grep through a directory, and extract the contents between the tags

If it has to be grep, use that command:

grep -PzoHnr "(?s)< start >.*< / start >" .

Explanation:

  • -P: Activate perl regular expressions
  • -z: Treat the input as a set of lines, each terminated by a zero byte
  • -o: Print only matches
  • -H: Add the filename in front of the match
  • -n: Add the line number in front of the match
  • -r: Read all files under each directory, recursively.
  • (?s): Activates PCRE_DOTALL, which means that . finds any character or newline
  • < start >.*< / start > is the regular expression

Alternatively, here is an awk solution as well:

awk '/\<\ start\ \>/,/\<\ \/\ start\ \>/{print FILENAME ":" FNR ":" $0}' $(find . -type f)

Explanation:

  • /\<\ start\ \>/,/\<\ \/\ start\ \>/: Finds all between < start > and < / start >
  • {print FILENAME ":" FNR ":" $0}: Prints the filename, the line number and the line
  • $(find . -type f) lists only the files in the directory recusively


Related Topics



Leave a reply



Submit