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



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

我将他们的路径/文件名复制粘贴到moveme.txt.

我在想cat moveme.txt | xargs command但我在那里放养。请帮忙。

我尝试cat moveme.txt | xargs -0 -I % sh -c 'sudo mv -v % /new/directory/'但失败了。如何做到这一点?

编辑: 我想补充一点,这个路径/文件名有空格。也许这很重要。

摘自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

建议在执行前试运行打印每个不可逆mvcmd:

awk '{cmd = "mv "" $0 "" /new/directory/"; print cmd}' moveme.txt

准备好执行mv命令时:

awk '{cmd = "mv "" $0 "" /new/directory/"; system(cmd)}' moveme.txt

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

sed -r 's|(^$)|mv "1" /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. $0需要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/'进行调试。您可以使用任何您喜欢的语言,例如nodesh -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/ {} +

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

最新更新