我想递归地批量复制并重命名目录中的所有文件。批量复制并重命名多个文件
我有这样的事情:
/dir/subdir/file.aa
/dir/subdir/fileb.aa
/dir/filec.aa
,并希望所有要复制的文件,因为这:
/newdir/1.xx
/newdir/2.xx
/newdir/3.xx
/newdir/4.xx
.. /newdir/nn.xx
哪有我在bash中做这个?
我想递归地批量复制并重命名目录中的所有文件。批量复制并重命名多个文件
我有这样的事情:
/dir/subdir/file.aa
/dir/subdir/fileb.aa
/dir/filec.aa
,并希望所有要复制的文件,因为这:
/newdir/1.xx
/newdir/2.xx
/newdir/3.xx
/newdir/4.xx
.. /newdir/nn.xx
哪有我在bash中做这个?
尝试一下。像这样:
num=0
for i in `find -name "*.aa"`; do
let num=num+1
cp $i newdir/$lc.xx
done
find -name "*.aa" | cat -n | while read n f; do
cp "$f" newdir/"$n".xx
done
将与(几乎)任何有效的文件名(除非你有它的换行符,这将允许为好)工作。
如果你不局限于外壳,在python另一种解决方案可能是
#!/usr/bin/env python
if __name__ == '__main__':
import sys
import os
import shutil
target = sys.argv[1]
for num, source in enumerate(sys.argv[2:]):
shutil.move(source, os.path.join(target, "%d.xx" % num))
,然后可以被称为
<script name> newdir *.aa
更好的解决方案。 – ypnos
我会尽量回答这个问题,但是这可能不是成为最佳解决方案,因为有许多工具可以用于此目的。
我解决这个问题的方法是编写一个函数,然后将这个函数应用到目录/子目录中的每个文件。假设你有多个内核/处理器,并且你的函数会比重命名和复制文件更耗费CPU资源,那么你也可以并行化任务。
的bash脚本应该是这样的:
#! /bin/bash
n=1
CopyAndRename() {
NEWNAME=$n.xx
cp "$i" /newdir/$NEWNAME
n=$[$n+1]
}
IFS=$'\n'
LIST=`find /dir -type f`
for i in $LIST; do
CopyAndRename $i
done
这也应该处理与空格和其他特殊字符的文件名。对于并行化,你可以使用一个程序prll,然后用
prll CopyAndRename $LIST
更换的循环,但这个真的是没有必要的重命名和复制。
使用GNU并行它看起来就像这样:
find ... | parallel cp {} /newdir/{#}.xx
将并行做到这一点(每个核心一个作业),这可以加快复制 - 这取决于你的存储系统上。
GNU Parallel是一个通用的并行程序,可以很容易地在同一台机器上或在您拥有ssh访问权限的多台机器上并行运行作业。
如果你想在4个CPU上运行32个不同的工作岗位,并行化直接的方式是在每个CPU上运行8个作业:
GNU并行,而不是产生一个新的进程时,一个完成 - 保持CPU的活跃,从而节省了时间:
安装
如果您的发行版没有打包GNU Parallel,则可以执行个人安装,但不需要root访问权限。它可以在10秒内通过这样来完成:
(wget -O - pi.dk/3 || curl pi.dk/3/ || fetch -o - http://pi.dk/3) | bash
对于其他安装选项见http://git.savannah.gnu.org/cgit/parallel.git/tree/README
了解更多
查看更多的例子:http://www.gnu.org/software/parallel/man.html
观看介绍视频: https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1
走过t他教程:http://www.gnu.org/software/parallel/parallel_tutorial.html
订阅邮件列表,以获得支持:https://lists.gnu.org/mailman/listinfo/parallel
感谢,而是采用NUM = NUM + 1,我不得不使用NUM = $((NUM + 1))。 –
此解决方案不处理所有文件名的方式。如果一个文件有一个空间或类似的文件,它会失败。 – glglgl
而不是'num = $((num + 1))',你可以简单地做'((num ++))'。 – norcalli