如何使用 bash 将文件列表从不同目录移动到新目录

How to move list of files from different directories to new directory using bash

我使用 find ./busd/ -type f -iname '*.pdf' | less 在我的第二个驱动器上查找 .pdf 文件,并且有数百个来自不同子目录的结果,但我只需要 copy/move selection of pdf files 到新目录。

我将他们的 paths/filenames 复制粘贴到 moveme.txt

我正在考虑 cat moveme.txt | xargs command,但我那里有货。请帮忙。

我尝试了 cat moveme.txt | xargs -0 -I % sh -c 'sudo mv -v % /new/directory/' 但失败了。如何正确执行此操作?

编辑: 我想补充一点,这个 path/filenames 有空格。也许这很重要。

摘自moveme.txt

./busd/0128/csm/sorting/read-ables/linus/CLI/Bash-Beginners-Guide-new.pdf
./busd/0128/csm/3t2/readables/etc/xulin/Shell Scripting.pdf
./busd/0128/csm/dais6/Dearables/assorted/Bash Pocket Reference - Arnold Robbins.pdf

建议 dry-run 在执行前打印每个 不可逆 mv cmd:

  awk '{cmd = "mv \"" [=10=] "\" /new/directory/"; print cmd}' moveme.txt

准备好执行mv命令时:

  awk '{cmd = "mv \"" [=11=] "\" /new/directory/"; system(cmd)}' moveme.txt

另一种选择是使用 sed 命令将 moveme.txt 文件转换为 bash 脚本,并在执行前检查 moveme.sh

  sed -r 's|(^$)|mv "" /new/directory/|' moveme.txt > moveme.sh

检查 moveme.sh 和 运行 它。

  chmod a+x ./moveme.sh
  bash ./moveme.sh
find ./busd/ -type f -iname '*.pdf' -print0 |
  xargs -0 -P0 sh -c 'mv -v "$@" /new/directory/' sh

说明

  1. 在没有 -print0 的情况下将 find 的标准输出通过管道传输到 xargs -0 毫无意义。 find 命令需要 -print0 选项,因为文件名可能有您提到的空格。
  2. 使用 xargs -I% 不会受益于 xargs -P NUMBER 的并行化功能。 xargs -P0 将利用所有 CPU 个内核。
  3. [=22=] 需要 sh -c '...' sh 的最后 sh。它可以是任意字符串,但您可能想要一个合理的名称。

自己动手

seq 100000 | sed 's/$/.pdf/' | xargs -P0 touch
mkdir -p new/directory
find . -type f -iname '*.pdf' -print0 |
  xargs -0 -P0 sh -c 'mv -v "$@" new/directory/' sh
  1. 删除-P0并查看时间成本的差异。
  2. 试试 xargs -pxargs -t 看看有多少参数 xargs 通过。
  3. 尝试 sh -c 'ruby -e "p ARGV" mv -v "$@" new/directory/' 进行调试。你可以使用任何你喜欢的语言,以node为例:sh -c 'node -e "console.log(process.argv.slice(1))" mv -v "$@" new/directory/'

作为一个选项,它可以在一个命令中完成:

find ./busd/ -type f -iname '*.pdf' -exec mv -t /target_directory/ {} +

find ./busd/ -type f -iname '*.pdf' -print -exec mv -t /target_directory/ {} +

将所有复制文件打印到终端