为何我的管道不工作?

为何我的管道不工作?

我正在尝试编写一个 bash 脚本,该脚本将查找我的下载文件夹中的所有 mp3 并将它们移动到音乐文件夹中。为什么此行不起作用?

find ./ -type f -name \*.mp3 | mv *.mp3 /home/mitch/Desktop/Music/$ARTIST

我尝试使用管道将第一个命令的信息转换到第二个命令,但我以前从未使用过管道,不知道我是否做错了或者我是否对它们的用途有错误的认识。

答案1

mv命令不使用其标准输入,因此您必须将标准输入转换为参数,为此可以使用xargs

find ./ -type f -name '*.mp3' | xargs mv -t /home/mitch/Desktop/Music/$ARTIST

另外,您可以直接使用以下-exec操作find

find ./ -type f -name '*.mp3' -exec mv {} /home/mitch/Desktop/Music/$ARTIST ';'

编辑

正如@geirha 指出的那样,如果文件名包含空格,第一个命令将不起作用。在这种情况下,它应该如下所示

find ./ -type f -name '*.mp3' -print0 | xargs -0 mv -t /home/mitch/Desktop/Music/$ARTIST

答案2

xargs 的优点是命令行扩展。如果您有一个命令返回大量文本(或一个命令返回许多文件),那么您将需要 xargs。

如果您的目录中有几千个文件并且想要在该列表上运行某个脚本,您可以尝试“ ./myprogram *”,但如果您的程序对参数的大小有任何限制,您可能会通过扩展 * 来破坏缓冲区。此外,命令行本身也有限制,因此命令可能会失败,因为命令行缓冲区溢出。使用 xargs 将避免此问题。

最后,find 上的 -print0 将在返回的文件名中放置空格的空分隔符,而 xargs 上的 -0 选项将解释这些空值。阅读man xargs

相关内容