批量复制和重命名多个文件

10

我想要批量复制和重命名一个目录下的所有文件,包括子目录。

我有如下代码:

/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中实现这个操作?

4个回答

5
find -name "*.aa" | cat -n | while read n f; do
    cp "$f" newdir/"$n".xx
done

这段代码可以适用于(几乎)任何有效的文件名(除非文件名中有换行符,这也是允许的)。

如果您不受shell的限制,另一种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

3

尝试像这样做:

num=0
for i in `find -name "*.aa"`; do
    let num=num+1
    cp $i newdir/$lc.xx
done

谢谢,我不得不使用num=$((num+1))而不是num=num+1。 - Leonardo M. Ramé
1
这个解决方案不能正确处理所有文件名。如果文件名中有空格或类似的字符,它会失败。 - glglgl
1
你可以使用(( num++ ))来代替num=$(( num+1)) - norcalli

0

我会尝试回答这个问题,但这可能不是最优解,因为有许多工具可以用于此。

我解决这个问题的方法是编写一个函数,然后将该函数应用于目录/子目录中的每个文件。假设您有多个核心/处理器,并且您的函数所做的事情比仅重命名和复制文件更消耗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的程序,然后将for循环替换为

prll CopyAndRename $LIST

但是这对于重命名和复制来说并不是必要的。


0

使用GNU Parallel,它会像这样:

 find ... | parallel cp {} /newdir/{#}.xx

它将以并行方式执行此操作(每个核心一个任务),这可能会加快复制速度-取决于您的存储系统。

GNU Parallel是一个通用的并行处理工具,可以轻松地在同一台机器上或具有ssh访问权限的多台机器上并行运行任务。

如果您有32个不同的任务要在4个CPU上运行,一种简单的并行化方法是在每个CPU上运行8个任务:

Simple scheduling

相比之下,GNU Parallel在一个进程完成时会生成一个新的进程 - 保持CPU活动状态,从而节省时间:

GNU Parallel scheduling

安装

如果您的发行版没有打包GNU Parallel,您可以进行个人安装,无需root访问权限。只需执行以下操作即可在10秒内完成:

$ (wget -O - pi.dk/3 || lynx -source pi.dk/3 || curl pi.dk/3/ || \
   fetch -o - http://pi.dk/3 ) > install.sh
$ sha1sum install.sh | grep 883c667e01eed62f975ad28b6d50e22a
12345678 883c667e 01eed62f 975ad28b 6d50e22a
$ md5sum install.sh | grep cc21b4c943fd03e93ae1ae49e28573c0
cc21b4c9 43fd03e9 3ae1ae49 e28573c0
$ sha512sum install.sh | grep da012ec113b49a54e705f86d51e784ebced224fdf
79945d9d 250b42a4 2067bb00 99da012e c113b49a 54e705f8 6d51e784 ebced224
fdff3f52 ca588d64 e75f6033 61bd543f d631f592 2f87ceb2 ab034149 6df84a35
$ bash install.sh

安装请参考 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

按照教程操作:http://www.gnu.org/software/parallel/parallel_tutorial.html

订阅邮件列表以获取支持:https://lists.gnu.org/mailman/listinfo/parallel


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接