How do you grep results from 'find'?

前端 未结 3 2120
情深已故
情深已故 2021-01-05 18:02

Trying to find a word/pattern contained within the resulting file names of the find command.

For instance, I have this command:

find . -name Gruntfile

相关标签:
3条回答
  • 2021-01-05 18:25

    Use the -exec {} + option to pass the list of filenames that are found as arguments to grep:

    find -name Gruntfile.js -exec grep -nw 'purifycss' {} +
    

    This is the safest and most efficient approach, as it doesn't break when the path to the file isn't "well-behaved" (e.g. contains a space). Like an approach using xargs, it also minimises the number of calls to grep by passing multiple filenames at once.

    I have removed the -e and -r switches, as I don't think that they're useful to you here.


    An excerpt from man find:

    -exec command {} +
    This variant of the -exec action runs the specified command on the selected files, but the command line is built by appending each selected file name at the end; the total number of invocations of the command will be much less than the number of matched files.

    0 讨论(0)
  • 2021-01-05 18:27

    When too many files exist for the * expansion to run:

    $ grep -o 'xxmaj\|xxbos\|xxfld' train/* | wc -l
    -bash: /bin/grep: Argument list too long
    0
    

    Then this code fixes the “too long” problem:

    $ find junk -maxdepth 1 -type f | xargs grep -o 'TVDetails\|xxmaj\|xxbos\|xxfld' 
    junk/gum-.doc.out:TVDetails
    junk/Zv0n.doc.out:TVDetails
    $ find junk -maxdepth 1 -type f | xargs grep -o 'TVDetails\|xxmaj\|xxbos\|xxfld' | wc -l
    2
    

    It runs faster on my system, and maybe yours, when using the -P 0 option:

    $ /usr/bin/time -f "%E Elapsed Real Time" find train -maxdepth 1 -type f | xargs -P 0 grep -o 'TVDetails\|xxmaj\|xxbos\|xxfld' | wc -l
    0:02.45 Elapsed Real Time
    358
    $ /usr/bin/time -f "%E Elapsed Real Time" find train -maxdepth 1 -type f | xargs grep -o 'TVDetails\|xxmaj\|xxbos\|xxfld' | wc -l
    0:11.96 Elapsed Real Time
    358
    

    Hope this helps.

    0 讨论(0)
  • 2021-01-05 18:35

    While this doesn't strictly answer your question, provided you have globstar turned on (shopt -s globstar), you could filter the results in bash like this:

    grep something **/Gruntfile.js
    

    I was using religiously the approach used by Tom Fenech until I switched to zsh, which handles such things much better. Now all I do is:

    grep text **/*(.)
    

    which greps text through all regular files in current directory.

    I believe this to be much cleaner syntax especially for day-to-day work in shell.

    0 讨论(0)
提交回复
热议问题