How to pipe list of files returned by find command to cat to view all the files

后端 未结 15 1321
庸人自扰
庸人自扰 2020-12-02 03:44

I am doing a find and then getting a list of files. How do I pipe it to another utility like cat (so that cat displays the contents of all those fi

相关标签:
15条回答
  • 2020-12-02 04:08

    There are a few ways to pass the list of files returned by the find command to the cat command, though technically not all use piping, and none actually pipe directly to cat.

    1. The simplest is to use backticks (`):

      cat `find [whatever]`
      

      This takes the output of find and effectively places it on the command line of cat. This doesn't work well if find has too much output (more than can fit on a command-line) or if the output has special characters (like spaces).

    2. In some shells, including bash, one can use $() instead of backticks :

      cat $(find [whatever])
      

      This is less portable, but is nestable. Aside from that, it has pretty much the same caveats as backticks.

    3. Because running other commands on what was found is a common use for find, find has an -exec action which executes a command for each file it finds:

      find [whatever] -exec cat {} \;
      

      The {} is a placeholder for the filename, and the \; marks the end of the command (It's possible to have other actions after -exec.)

      This will run cat once for every single file rather than running a single instance of cat passing it multiple filenames which can be inefficient and might not have the behavior you want for some commands (though it's fine for cat). The syntax is also a awkward to type -- you need to escape the semicolon because semicolon is special to the shell!

    4. Some versions of find (most notably the GNU version) let you replace ; with + to use -exec's append mode to run fewer instances of cat:

      find [whatever] -exec cat {} +
      

      This will pass multiple filenames to each invocation of cat, which can be more efficient.

      Note that this is not guaranteed to use a single invocation, however. If the command line would be too long then the arguments are spread across multiple invocations of cat. For cat this is probably not a big deal, but for some other commands this may change the behavior in undesirable ways. On Linux systems, the command line length limit is quite large, so splitting into multiple invocations is quite rare compared to some other OSes.

    5. The classic/portable approach is to use xargs:

      find [whatever] | xargs cat
      

      xargs runs the command specified (cat, in this case), and adds arguments based on what it reads from stdin. Just like -exec with +, this will break up the command-line if necessary. That is, if find produces too much output, it'll run cat multiple times. As mentioned in the section about -exec earlier, there are some commands where this splitting may result in different behavior. Note that using xargs like this has issues with spaces in filenames, as xargs just uses whitespace as a delimiter.

    6. The most robust, portable, and efficient method also uses xargs:

      find [whatever] -print0 | xargs -0 cat
      

      The -print0 flag tells find to use \0 (null character) delimiters between filenames, and the -0 flag tells xargs to expect these \0 delimiters. This has pretty much identical behavior to the -exec...+ approach, though is more portable (but unfortunately more verbose).

    0 讨论(0)
  • 2020-12-02 04:08

    Use ggrep.

    ggrep -H -R -I "mysearchstring" *
    

    to search for a file in unix containing text located in the current directory or a subdirectory

    0 讨论(0)
  • 2020-12-02 04:08

    Are you trying to find text in files? You can simply use grep for that...

    grep searchterm *
    
    0 讨论(0)
  • 2020-12-02 04:09

    Modern version

    POSIX 2008 added the + marker to find which means it now automatically groups as many files as are reasonable into a single command execution, very much like xargs does, but with a number of advantages:

    1. You don't have to worry about odd characters in the file names.
    2. You don't have to worry about the command being invoked with zero file names.

    The file name issue is a problem with xargs without the -0 option, and the 'run even with zero file names' issue is a problem with or without the -0 option — but GNU xargs has the -r or --no-run-if-empty option to prevent that happening. Also, this notation cuts down on the number of processes, not that you're likely to measure the difference in performance. Hence, you could sensibly write:

    find . -exec grep something {} +
    

    Classic version

    find . -print | xargs grep something
    

    If you're on Linux or have the GNU find and xargs commands, then use -print0 with find and -0 with xargs to handle file names containing spaces and other odd-ball characters.

    find . -print0 | xargs -0 grep something
    

    Tweaking the results from grep

    If you don't want the file names (just the text) then add an appropriate option to grep (usually -h to suppressing 'headings'). To absolutely guarantee the file name is printed by grep (even if only one file is found, or the last invocation of grep is only given 1 file name), then add /dev/null to the xargs command line, so that there will always be at least two file names.

    0 讨论(0)
  • 2020-12-02 04:10

    This will print the name and contents of files-only recursively..

    find . -type f -printf '\n\n%p:\n' -exec cat {} \;
    

    Edit (Improved version): This will print the name and contents of text (ascii) files-only recursively..

    find . -type f -exec grep -Iq . {} \; -print | xargs awk 'FNR==1{print FILENAME ":" $0; }'
    

    One more attempt

    find . -type f -exec grep -Iq . {} \; -printf "\n%p:" -exec cat {} \;
    
    0 讨论(0)
  • 2020-12-02 04:15

    The find command has an -exec argument that you can use for things like this, you could just do the grep directly using that.

    For example (from here, other good examples at this page):

    find . -exec grep "www.athabasca" '{}' \; -print 
    
    0 讨论(0)
提交回复
热议问题