如何使用管道从另一个命令的标准输入中引用一个命令的标准输出?

如何使用管道从另一个命令的标准输入中引用一个命令的标准输出?

我试图了解如何将 stdout 用作另一个命令的 stdin。为了测试它,我尝试使用以下命令从当前文件夹中删除所有目录。

ls -d -- */ | rm -rf $1

我希望 ls -d -- */ 的结果能够通过管道传输到 rm 的输入中,但是它不起作用。有什么想法吗?

答案1

并非所有命令/程序都会直接接受管道输入(包括)。另外,为什么在脚本之外rm使用 bash 替换变量?$1

对于一般情况,您需要查看xargs,这是一个实用程序,其目标是通过从 stdin 获取列表,然后使用该列表的元素(以不同的可能方式)调用命令来简化此类场景。

对于您想要做的事情...(明智地使用它!):(rm -rf *.)就足够了。

答案2

find -maxdepth 1 -not -name ".*" -type d -print0 | xargs -n1 -0 rm -rf

-maxdepth 1仅包括当前目录。-not -name ".*"排除隐藏目录。-type d仅包括目录,不包括文件。find -print0与一起使用xargs -0将使用名称带有奇怪字符的文件和目录。xargs -n1一次执行一行命令(在本例中为 rm)。

答案3

两个选项:

ls -d -- */ | xargs rm -r

或者

rm -r `ls -d -- */`

过去,xargs 是必需的,因为命令行参数列表有限制。xargs 会为每次执行设置一个合理的数字,并多次运行给定的命令(它还有一些很酷的东西可以帮助您进行并发执行)。然而,在最近的内核中,这个限制已经消失,因此更简单的没有管道的 rm 命令可以正常工作,尽管它会占用更多的 RAM,因此如果有成千上万个参数,xargs 仍然会更高效。

值得注意的是,您不需要-frm,因为只有当文件不存在时您希望 rm 继续,或者跳过任何交互式确认时才需要它。由于您有 ls 告诉您它们存在,所以最好不要使用它,然后通常的别名-i将使您免于意外删除写保护的文件和目录。

答案4

在这种特定情况下,您还可以使用find

find . -maxdepth 1 -type -d -exec rm -rf {} \;

相关内容