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

Bash 批量复制和重命名多个文件,bash,Bash,我想批量复制和重命名一个目录中的所有文件,递归 我有这样的想法: /dir/subdir/file.aa /dir/subdir/fileb.aa /dir/filec.aa num=0 for i in `find -name "*.aa"`; do let num=num+1 cp $i newdir/$lc.xx done #! /bin/bash n=1 CopyAndRename() { NEWNAME=$n.xx cp "$i" /newdir/$NE

我想批量复制和重命名一个目录中的所有文件,递归

我有这样的想法:

/dir/subdir/file.aa
/dir/subdir/fileb.aa
/dir/filec.aa
num=0
for i in `find -name "*.aa"`; do
    let num=num+1
    cp $i newdir/$lc.xx
done
#! /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
 find ... | parallel cp {} /newdir/{#}.xx
并希望复制所有文件,如下所示:

/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
num=0
for i in `find -name "*.aa"`; do
    let num=num+1
    cp $i newdir/$lc.xx
done
#! /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
 find ... | parallel cp {} /newdir/{#}.xx
将使用(几乎)任何有效的文件名(除非其中有换行符,这也是允许的)

如果您不局限于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
newdir*.aa

我将尝试回答这个问题,但这可能不是最佳解决方案,因为有许多工具可用于此

我解决这个问题的方法是编写一个函数,然后将该函数应用于目录/子目录中的每个文件。假设您有多个内核/处理器,并且您的函数将执行比重命名和复制文件更耗费CPU的操作,那么您也将并行化该任务

bash脚本如下所示:

/dir/subdir/file.aa
/dir/subdir/fileb.aa
/dir/filec.aa
num=0
for i in `find -name "*.aa"`; do
    let num=num+1
    cp $i newdir/$lc.xx
done
#! /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
 find ... | parallel cp {} /newdir/{#}.xx
这还应该处理带有空格和其他特殊字符的文件名。对于并行化,您可以使用程序prll,然后将For循环替换为

prll CopyAndRename $LIST

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

使用GNU Parallel时,它将如下所示:

/dir/subdir/file.aa
/dir/subdir/fileb.aa
/dir/filec.aa
num=0
for i in `find -name "*.aa"`; do
    let num=num+1
    cp $i newdir/$lc.xx
done
#! /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
 find ... | parallel cp {} /newdir/{#}.xx
它将并行执行此操作(每个核心一个作业),这可能会加快复制速度,具体取决于您的存储系统

GNU Parallel是一个通用的并行程序,它使得在同一台机器上或在您有ssh访问权的多台机器上并行运行作业变得非常容易

如果您有32个不同的作业要在4个CPU上运行,并行化的直接方法是在每个CPU上运行8个作业:

GNU Parallel会在完成时生成一个新进程—使CPU保持活动状态,从而节省时间:

安装

如果您的发行版没有打包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 c82233e7da3166308632ac8c34f850c0
12345678 c82233e7 da316630 8632ac8c 34f850c0
$ md5sum install.sh | grep ae3d7aac5e15cf3dfc87046cfc5918d2
ae3d7aac 5e15cf3d fc87046c fc5918d2
$ sha512sum install.sh | grep dfc00d823137271a6d96225cea9e89f533ff6c81f
9c5198d5 31a3b755 b7910ece 3a42d206 c804694d fc00d823 137271a6 d96225ce
a9e89f53 3ff6c81f f52b298b ef9fb613 2d3f9ccd 0e2c7bd3 c35978b5 79acb5ca
$ bash install.sh
有关其他安装选项,请参阅

了解更多信息

请参阅更多示例:

观看介绍视频:

浏览本教程:


注册电子邮件列表以获得支持:

谢谢,我没有使用num=num+1,而是使用num=$((num+1))。此解决方案不会以应有的方式处理所有文件名。如果文件中有空格或类似空格,则会失败。您只需执行
((num++)
,而不是
num=$((num+1))