使用 find + xargs 移动文件:目标不是目录?

Ame*_*ina 9 find xargs

当我运行以下命令时:

> mkdir some_dir
> find /foo/bar/ -name '*.csv' -print0 | xargs -0 mv {} some_dir
Run Code Online (Sandbox Code Playgroud)

我收到数百行说:

mv: target `/foo/bar/XX.csv` is not a directory
Run Code Online (Sandbox Code Playgroud)

为什么?我认为 xargs 会执行:

mv /foo/barXX.csv some_dir
Run Code Online (Sandbox Code Playgroud)

对于find找到的每个文件。这是怎么回事?顺便说一句,这是与zsh

更新:

更新1:

我试过:

find /foo/bar/ -name '*.csv' -print0 | xargs -0 mv {} -t some_dir
Run Code Online (Sandbox Code Playgroud)

但后来我得到了几行:

mv: cannot stat `{}': No such file or directory
Run Code Online (Sandbox Code Playgroud)

虽然我认为该命令正在正确移动我的文件。

更新2:

单独-t使用时,我似乎不需要该选项mv。例如

> touch file1.txt
> touch file2.txt
> mkdir my_dir
> mv  file1.txt  file2.txt  my_dir
Run Code Online (Sandbox Code Playgroud)

效果很好。为什么我-t在使用时需要xargs

slm*_*slm 15

假设您有 GNU ( find, xargs, & mv),请将您的命令更改为:

$ find /foot/bar/ -name '*.csv' -print0 | xargs -0 mv -t some_dir
Run Code Online (Sandbox Code Playgroud)

摘自mv手册页

   -t, --target-directory=DIRECTORY
          move all SOURCE arguments into DIRECTORY
Run Code Online (Sandbox Code Playgroud)

上面xargs ...将构造命令,以便调用 move 将如下所示:

 $ mv 1.csv 2.csv 3.csv ... -t some_dir
Run Code Online (Sandbox Code Playgroud)

不需要 xargs

您可以通过自己find完成所有工作来跳过这种方法:

$ find /foot/bar/ -name '*.csv' -exec mv -t some_dir {} +
Run Code Online (Sandbox Code Playgroud)

你为什么需要mv -t ...

这与xargs构建文件集以传递给每次将要运行的命令(即mv ...)的方式有关。

当您mv自己手动运行命令时,您可以控制传递给它的文件名数量,因此您无需担心需要 ,-t my_dir因为您总是将目标目录放在最后。

参考