将一个扩展名的文件移动到目录时使用错误

时间:2019-02-28 21:43:12

标签: bash grep

我的扩展名为.mp3的文件位于目录的不同文件夹中,我需要将它们全部移动到一个目录中才能使用。我看过关于SO的多个教程和问题,无论我尝试什么,我要么得到

    usage: mv [-f | -i | -n] [-v] source target
    mv [-f | -i | -n] [-v] source ... directory

或“没有这样的文件或目录”。

进入每个单独的文件夹太多了,但是现在我进入其中一个文件夹。与此:

    mv *.mp3 /Users/myname/Volumes/LaCie/model/folder/media

我收到上面的“用法”错误。我看着Moving files to a directory并尝试:

    find . | grep ".mp3" | xargs mv /Users/myname/Volumes/LaCie/model/folder/media

并得到相同的错误。

我在做什么错?正确的语法是什么?另外,如果我位于包含文件目录的目录中,但不在该目录本身中,我是否可以提取mp3文件并移动它们?我感谢对此的见解。谢谢。

编辑:此问题的主要部分是使用/ Volumes时,路径以/ Volumes开头。我正在执行/ Users / myname / Volumes,这就是我遇到很多麻烦的原因之一。

2 个答案:

答案 0 :(得分:2)

mv有不同的实现和版本。您可以使用man mv检查版本的允许语法。

  • 如果您有GNU mv,则可以使用mv -t target/dir *.mp3
  • 大多数实现应支持mv *.mp3 target/dir
  • 如果您的mv仅支持mv source target的绝对最小值,并且仅包含一个源文件和一个目标文件,则可以使用以下命令,如果存在target/dir/,该命令应始终有效。

for i in *.mp3; do mv "$i" "target/dir/$i"; done

答案 1 :(得分:2)

您使用xargs的方式的问题在于,默认情况下,xargs会将 append 附加到您提供的命令字符串末尾。因此,您最终将运行一堆看起来像这样的mv命令:

mv /Users/myname/Volumes/LaCie/model/folder/media foo.mp3

您可以通过告诉xargs将参数放在命令中的位置来解决此问题:

<other commands> | xargs -I{} mv {} /Users/myname/Volumes/LaCie/model/folder/media

通过-I选项,您可以提供任意字符串作为args存放位置的占位符。我之所以使用{}只是因为这似乎是您在类似上下文中使用的常规令牌(例如,与-exec的{​​{1}}选项一起使用,如下所示)。

但是,使用find命令的find选项有一种更简单的方法:

-exec

还要注意find . -name '*.mp3' -exec mv {} /Users/myname/Volumes/LaCie/model/folder/media \; 部分,它使您可以摆脱-name '*.mp3'部分。

最后,为了安全起见,我个人将| grep ".mp3"放在目标路径的末尾。如果/中不存在media目录,或者该位置中存在名为/Users/myname/Volumes/LaCie/model/folder的非目录项(例如常规文件或符号链接),则{上面的{1}}命令将很高兴地一次将您的所有mp3文件移动到该文件夹​​中,每次都在其中创建一个名为media file 。除了最后一个文件(现在将是名为find的文件)之外,您将丢失所有em的mp3文件。

但是,如果尾随media,如果media不是目录,则/命令将失败,并显示一条错误消息。因此,修改后的命令将是:

media

更新:根据下面的Gordon Davisson的评论,您还应该考虑将mvfind . -name '*.mp3' -exec mv {} /Users/myname/Volumes/LaCie/model/folder/media/ \; 添加到-i命令中,以避免意外覆盖重复的文件名称。例如,如果您有-nmv,则上面的命令将覆盖另一个命令。 a/foo.mp3选项将导致b/foo.mp3提示您确认每个文件移动,而-i选项(也称为mv)将防止-n覆盖文件如果已经存在同名文件。