管道式xargs后的管道命令


38

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是我想要的。


2
您应该引用*log*否则shell将对其进行扩展。
Anthon 2015年

请注意,sh -c期望将命令名称(参数0)作为其第二个参数,因此您应该始终这样做find . -type d -name *log* | xargs sh -c "ls -ltr | tail -10" lstail(注意lstail最后的,这将$0与创建的shell一样)。否则,您的第一个结果将填补该角色而无法使用。
乔纳斯(Jonas)

Answers:


57

你快到了 在您的最后一个命令,就可以使用-I到做ls正确

-I replace-str

    将初始参数中出现的replace-str替换为从标准输入中读取的名称。同样,未加引号的空格也不会终止输入项目。相反,分隔符是换行符。表示-x-L 1

因此,

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

您将echo找到的目录find,然后ls | tail对其进行处理。


找 。类型d-名称“ log ” | xargs -I {} sh -c“ echo {}; ls -ltr {} | grep -E \” file_in | file_out \“ || tail -5”我使用了这个。
anotherperson1 2015年

3
我做xargs -n 1 sh -c 'echo $0'
Ginhing

1
在macOS上,替换操作在加引号的命令内无效,因此echo $0很有帮助(且更易于理解)
mpuncel

1
为了使它与空间,使用文件名的工作-print0xargs -0并逃离{}到双引号sh命令:find . -type d -name "*log*" -print0 | xargs -0 -I {} sh -c "echo \"{}\";ls -la \"{}\" | tail -2"
贝内迪克特·科佩尔

我使用“ xargs -n 1 sh -c” echo \ $ 0 | $ func“`如果我需要使用$ func变量


2

除了fredtantini之外,并作了一般性说明(由于文档有些混乱):

xargs -I {}会从标准输入“{}”字符和,无坚不摧从管替换它们。这意味着您实际上可以{}用任何字符组合替换(也许是为了更好地适应您喜欢的编程风格)。例如xargs -I % sh -c "echo %"。如果您始终使用,则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 {}命令中,同样的事情再次发生。将{}被替换为预管命令的内容。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.