在管道 xargs 之后管道命令

在管道 xargs 之后管道命令

HP-UX ***** B.11.23 U ia64 **** 无限用户许可证

find . -type d -name *log* | xargs ls -la

给我目录名称(目录名称中包含的名称log),后跟该目录中的所有文件。

目录  /var/opt/SID/application_a/log/、  /var/opt/SID/application_b/log/等  /var/opt/SID/application_c/log/包含日志文件。

我只想通过命令列出两个最新的日志文件ls,我通常使用ls -latr | tail -2.

输出必须是这样的..

/var/opt/SID/application_a/log/
-rw-rw-rw-   1 user1    user1      59698 Jun 11  2013 log1
-rw-rw-rw-   1 user1    user1      59698 Jun 10  2013 log2
/var/opt/SID/application_b/log/
-rw-rw-rw-   1 user1    user1      59698 Jun 11  2013 log1
-rw-rw-rw-   1 user1    user1      59698 Jun 10  2013 log2
/var/opt/SID/application_c/log/
-rw-rw-rw-   1 user1    user1      59698 Jun 11  2013 log1
-rw-rw-rw-   1 user1    user1      59698 Jun 10  2013 log2

find . -type d -name *log* | xargs ls -la | tail -2没有给我上面的结果。我得到的是命令的最后两个文件的列表 find . -type d -name *log* | xargs ls -la

那么我可以在管道之后管道命令吗xargs?我还如何查询以获取上述格式的文件结果列表?

find . -type d -name *log* | xargs sh -c "ls -ltr | tail -10"

给我当前目录中的十个目录名称的列表,这恰好是/var/opt/SID,但这也不是我想要的。

答案1

你快到了。在你的最后一个命令中,你可以使用来正确-I执行ls

-I replace-str

    替换出现的替换-str在初始参数中,名称从标准输入读取。此外,不带引号的空格不会终止输入项;相反,分隔符是换行符。意味着-x-L 1

所以,与

find . -type d -name "*log*" | xargs -I {} sh -c "echo {}; ls -la {} | tail -2"

您将找到echo由 找到的目录find,然后ls | tail对其执行操作。

答案2

除了 fredtantini 之外,作为一般性说明(因为文档有点令人困惑):

将从xargs -I {}标准输入中获取“{}”字符,并将它们替换为来自管道的任何内容。这意味着您实际上可以替换{}为任何字符组合(也许是为了更好地适合您喜欢的编程风格)。例如: xargs -I % sh -c "echo %"。如果您总是使用 ,则xargs -I {}可以将其替换为 ,xargs -i因为它是简写。编辑:该xargs -i选项已被弃用,因此请坚持使用xargs -I{}.

它将sh -c告诉您的 bash/shell 从字符串而不是从标准输入读取下一个命令。所以写作sh -c "echo something"就相当于echo something

将读取您使用其xargs -I {} sh -c "echo {}"创建的输入。既然您告诉它用从管道获得的参数进行替换,那么就会发生这种情况。sh -cecho {}{}

即使没有管道,您也可以轻松测试它,只需在终端中键入上述命令即可。接下来您写的任何内容都将输出到终端(Ctrl-D 退出)。

ls -la {}命令中同样的事情再次发生。被{}替换为预管道命令的内容。

答案3

GNU Parallel 使此类任务变得简单:

find . -type d -name "*log*" | parallel --tag "ls -la {} | tail -2"

如果您不想完全安装 GNU Parallel,您可以进行最小安装:http://git.savannah.gnu.org/cgit/parallel.git/tree/README

相关内容