我正在做一个find,然后获取文件列表。我如何将其通过管道传输到另一个实用程序cat(例如,cat显示所有这些文件的内容),并且基本上需要grep这些文件中的某些内容。
我正在做一个find,然后获取文件列表。我如何将其通过管道传输到另一个实用程序cat(例如,cat显示所有这些文件的内容),并且基本上需要grep这些文件中的某些内容。
Answers:
传递到另一个进程(尽管这不会完成您说的那样):
command1 | command2
这将发送命令1的输出作为命令2的输入
-exec上find(这将完成您想做的-但特定于find)
find . -name '*.foo' -exec cat {} \;
(find和之间的所有内容-exec都是您已在使用的查找谓词。 {}它将您找到的特定文件替换为命令(cat {}在本例中为);\;是结束-exec命令。)
将一个进程的输出作为命令行参数发送到另一进程
command2 `command1`
例如:
cat `find . -name '*.foo' -print`
(注意,这些都是反引号不正规报价(我的键盘上的波浪线〜之下)。)这将输出发送command1到command2作为命令行参数。请注意,包含空格(换行符等)的文件名将分成单独的参数。
find允许您编写:find . -name '*.foo' -exec cat {} +,其中的+表示find应将尽可能方便的文件名分组为单个命令调用。这非常有用(它无需使用-print0and 即可处理文件名中的空格等xargs -0)。
find . -name '*.foo' | xargs cat
find . -name '*.foo' | xargs cat | grep string
POSIX 2008添加了+标记,find这意味着它现在可以自动将尽可能多的文件分组到一个命令执行中,这非常相似xargs,但是具有许多优点:
文件名问题是xargs不带-0选项的问题,而“即使文件名为零也可以运行”问题是带或不带-0选项的问题-但是GNU xargs具有-r或--no-run-if-empty选项来防止这种情况的发生。而且,此表示法减少了进程数,而不是您可能要衡量性能差异。因此,您可以明智地编写:
find . -exec grep something {} +
find . -print | xargs grep something
如果您使用的是Linux或具有GNU find和xargs命令,则使用-print0with find和-0with xargs处理包含空格和其他奇数字符的文件名。
find . -print0 | xargs -0 grep something
grep如果您不希望使用文件名(仅文本),则添加一个适当的选项grep(通常-h是禁止显示“标题”)。为了绝对保证文件名的打印方式grep(即使仅找到一个文件,或者最后一次调用grep仅给出1个文件名),然后将其添加/dev/null到xargs命令行中,以便始终至少有两个文件名。
xargs grep something。
find管道传递到的标准输入xargs。该xargs程序读取它的标准输入,在白空间分割输入(空格,新行,制表符,等),并附加一个数字的话到命令grep something并执行该命令行。xargs然后继续读取输入并执行命令,直到输入用完。根据给出的输入,尽可能多地xargs运行grep命令(find在此示例中)。
/dev/null会丢失错误消息。
有几种方法可以将find命令返回的文件列表传递给cat命令,尽管从技术上讲并不是全部使用管道,也没有一种方法直接将管道直接传递给cat。
最简单的是使用反引号(`):
cat `find [whatever]`
这将获取的输出find并将其有效地放置在的命令行上cat。如果find输出过多(超出命令行的大小)或输出具有特殊字符(如空格),则此方法将无法正常工作。
在包括在内的某些shell中,bash可以使用$()而不是反引号:
cat $(find [whatever])
这不太方便携带,但可以嵌套。除此之外,它还有与反引号相同的警告。
因为在找到的内容上运行其他命令是的常见用法find,find具有一个-exec操作,它针对找到的每个文件执行一个命令:
find [whatever] -exec cat {} \;
的{}是文件名的占位符,和\;该命令的结束标记(这是可能有后其他动作-exec。)
这将对cat每个文件运行一次,而不是运行cat向其传递多个文件名的单个实例,这可能效率低下,并且可能没有某些命令所希望的行为(尽管可以使用cat)。语法也很难输入-您需要转义分号,因为分号是shell特有的!
的某些版本find(最引人注目的是GNU版本)让你更换;与+到使用-exec的附加模式运行的实例少cat:
find [whatever] -exec cat {} +
这将通过多个文件名到的每次调用cat,其可以是更有效的。
请注意,但这不能保证使用单个调用。如果命令行太长,则参数分布在的多个调用中cat。因为cat这可能没什么大不了的,但是对于某些其他命令,这可能会以不希望的方式更改行为。在Linux系统上,命令行长度限制非常大,因此与其他某些OS相比,分成多个调用的情况很少见。
经典/便携式方法是使用xargs:
find [whatever] | xargs cat
xargs运行指定的命令(cat在这种情况下为),并根据从stdin中读取的内容添加参数。就像-exec用+,这将在必要时向上突破的命令行。也就是说,如果find产生太多输出,它将运行cat多次。如前一节所述-exec,有一些命令可能会导致这种行为不同。请注意,xargs像这样使用时,文件名中的空格会出现问题,xargs就像使用空格作为分隔符一样。
最健壮,便携式和高效的方法还使用xargs:
find [whatever] -print0 | xargs -0 cat
该-print0标志指示在文件名之间find使用\0(空字符)定界符,并且-0标志指示xargs期望这些\0定界符。这种行为与-exec... +方法几乎具有相同的行为,但更便于携带(但不幸的是更冗长)。
ls。
$()也可用于以外的命令find 。
find命令具有-exec参数,您可以将其用于诸如此类的事情,您可以直接使用它来执行grep。
例如(从此处,此页面上的其他好示例):
find . -exec grep "www.athabasca" '{}' \; -print
在bash中,以下内容比较合适:
find /dir -type f -print0 | xargs -0i cat {} | grep whatever
这将在/dir目录中找到所有文件,并安全地将文件名输送到xargs,这些文件名将安全地驱动器grep。
xargs如果您有成千上万个文件,则跳过不是一个好主意/dir;cat将由于参数列表长度过长而中断。xargs将为您解决所有问题。
的-print0参数find与的-0参数啮合以xargs正确处理带有空格的文件名。该-i给的说法xargs让你插入在需要的文件名cat的命令行。括号被替换为cat从中传递到命令的文件名find。
这将以递归方式仅打印文件的名称和内容。
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 {} \;
find -name '*.foo' -print对我非常