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 -c
echo {}
{}
即使没有管道,您也可以轻松测试它,只需在终端中键入上述命令即可。接下来您写的任何内容都将输出到终端(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