我正在查找文件列表。

我如何将它输送到另一个实用程序,如cat,以便cat显示所有这些文件的内容?

然后,我将使用grep来搜索这些文件中的一些文本。


对我来说,听起来像是shell脚本的工作:

for file in 'find -name *.xml'
do
   grep 'hello' file
done

或者类似的东西


现代版

POSIX 2008添加了+标记来查找,这意味着它现在自动将尽可能多的文件分组到单个命令执行中,非常像xargs,但有一些优点:

您不必担心文件名中的奇数字符。 您不必担心使用零文件名调用命令。

文件名问题是在没有-0选项的xargs中出现的,“即使没有文件名也运行”问题是在没有-0选项的情况下出现的,但是GNU xargs有-r或——no-run-if-empty选项来防止这种情况发生。此外,这种表示法减少了进程的数量,并不是说您可能会度量性能上的差异。因此,你可以这样写:

find . -exec grep something {} +

经典的版本

find . -print | xargs grep something

如果您使用的是Linux,或者有GNU的find和xargs命令,那么使用-print0和find一起使用,-0和xargs一起使用来处理包含空格和其他奇怪字符的文件名。

find . -print0 | xargs -0 grep something

从grep调整结果

如果你不想要文件名(只是文本),那么在grep中添加一个适当的选项(通常是-h来抑制“标题”)。为了绝对保证grep打印文件名(即使只找到一个文件,或者最后一次调用grep只给出了一个文件名),然后在xargs命令行中添加/dev/null,这样至少会有两个文件名。


find命令有一个-exec参数,你可以用它来做类似的事情,你可以直接用它来做grep。

例如(从这里,其他好的例子在本页):

find . -exec grep "www.athabasca" '{}' \; -print 

您正在尝试在文件中查找文本吗?你可以简单地使用grep…

grep searchterm *

有几种方法可以将find命令返回的文件列表传递给cat命令,但从技术上讲,并非所有方法都使用管道,也没有一种方法实际上直接通过管道传递给cat。

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). 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. 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! 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. 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. 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).


Piping to another process (although this won't accomplish what you said you are trying to do): command1 | command2 This will send the output of command1 as the input of command2. -exec on a find (this will do what you want to do, but it's specific to find): find . -name '*.foo' -exec cat {} \; Everything between find and -exec are the find predicates you were already using. {} will substitute the particular file you found into the command (cat {} in this case); the \; is to end the -exec command. Send output of one process as command line arguments to another process: command2 `command1` For example: cat `find . -name '*.foo' -print` Note these are backquotes not regular quotes (they are under the tilde ~ on my keyboard). This will send the output of command1 into command2 as command line arguments. It's called command substitution. Note that file names containing spaces (newlines, etc) will be broken into separate arguments, though.


列出并查看服务器上/ghi和/jkl目录下所有abc.def文件的内容

find /ghi /jkl -type f -name abc.def 2> /dev/null -exec ls {} \; -exec cat {} \;

要列出带有注释条目的abc.def文件并显示,请查看目录/ghi和/jkl中的这些条目

find /ghi /jkl -type f -name abc.def 2> /dev/null -exec grep -H ^# {} \;

在bash中,以下代码是合适的:

find /dir -type f -print0 | xargs -0i cat {} | grep whatever

这将找到/dir目录下的所有文件,并安全地将文件名输送到xargs中,xargs将安全地驱动grep。

如果你在/dir目录下有成千上万的文件,跳过xargs不是一个好主意;Cat将由于参数列表长度过大而中断。Xargs会帮你处理的。

-print0参数用于查找与xargs的-0参数相匹配,以正确处理带有空格的文件名。xargs的-i参数允许您在cat命令行中插入所需的文件名。括号被从find导入cat命令的文件名所取代。


以下是我的常用镜头:

grep YOURSTRING `find .`

它将打印文件名


这对我很有用

find _CACHE_* | while read line; do
    cat "$line" | grep "something"
done

为了实现这一点(使用bash),我将这样做:

cat $(find . -name '*.foo')

这就是所谓的“命令替换”,它在默认情况下去掉换行,这真的很方便!

更多信息请点击这里


使用ggrep。

ggrep -H -R -I "mysearchstring" *

在Unix中搜索包含位于当前目录或子目录中的文本的文件


下面是我找到包含一些我感兴趣的内容的文件名的方法,只是一个简单的bash行,很好地处理文件名中的空格:

find . -name \*.xml | while read i; do grep '<?xml' "$i" >/dev/null; [ $? == 0 ] && echo $i; done

我使用的方法是这样的:

find . -name <filename> -print0 | xargs -0 cat | grep <word2search4>

"find"的"-print0"参数和"xargs"的"-0"参数需要正确处理文件路径/名称中的空白。


这将只递归地打印文件的名称和内容。

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

编辑(改进版): 这将只递归地打印文本(ascii)文件的名称和内容。

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

再试一次

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