如何减少目录中每个文件名中的数字?

时间:2013-07-23 20:01:51

标签: bash sed

在我的终端上运行“ls -lrt”我得到一个大的列表,看起来像这样:

-rw-r--r--  1 pratik  staff   1849089 Jun 23 12:24 cam13-vid.webm
-rw-r--r--  1 pratik  staff   1850653 Jun 23 12:24 cam12-vid.webm
-rw-r--r--  1 pratik  staff   1839110 Jun 23 12:24 cam11-vid.webm
-rw-r--r--  1 pratik  staff   1848520 Jun 23 12:24 cam10-vid.webm
-rw-r--r--  1 pratik  staff   1839122 Jun 23 12:24 cam1-vid.webm

我上面仅展示了部分内容作为样本。

我想将所有文件重命名为比当前文件小一号。

例如,

mv cam1-vid.webm cam0-vid.webm
mv cam2-vid.webm cam1-vid.webm
.....
....
mv cam 200-vid.webm cam199-vid.webm

如何使用os x / linux bash脚本(也许使用sed)来完成?

3 个答案:

答案 0 :(得分:3)

你可以用普通的bash来做到这一点:

for i in {1..200}
do
    mv "cam${i}-vid.webm" "cam$((i-1))-vid.webm"
done

答案 1 :(得分:1)

我会使用find,拆分文件名,找到数字,减去一个,然后重命名:

find . -name "cam*-vid.webm" -print0 | while read -d\$0 old_name
do
    number=${old_name#cam}        #Filter left to remove 'cam' prefix
    number=${number%-vid.webm"}   #Filter right to remove '-vid.webm' suffix
    $((number -= 1))
    new_name="cam${number}-vid.webm"
    echo "mv \"$old_name\" \"$new_name\""
done | tee results

这只会打印出命令(这就是我echo的原因)。我将它传播到名为results的文件中。完成此命令后,请查看results并确保它完成所有应有的操作。只要有这样的操作,就会出现令人讨厌的惊喜。例如,如果我在重命名cam02-vid.webm之前将cam01-vid.webm重命名为cam01-vid.webm,我将覆盖cam01-vid-webm

也许更安全的方法是明确提供我需要的文件编号:

for number in {1..200}
do
    $((old_number = $number + 1))
    echo mv "\"cam${old_number}-vid.webm\" \"cam${number}-vid.webm\""
done | tee results

有用的提示:如果result文件看起来不错,您实际上可以将其作为shell脚本运行:

 $ bash results

另一种可能性是测试以确保旧文件存在:

for number in {1..200}
do
    $((old_number = $number + 1))
    if [ -f "$cam${old_number}-vid.webm" ]
    then
        echo mv "\"cam${old_number}-vid.webm\" \"cam${number}-vid.webm\""
    else
        echo "ERROR: Can't find a file called 'cam${old_number}-vid.webm'"
    fi
done | tee results

答案 2 :(得分:0)

解决方案。

首先它遍历所有输入文件(@ARGV)并过滤那些普通文件而不是链接(grep),提取数字(map)并按数字顺序排序上升到避免重写(sort)。稍后创建一个新文件,减少数字并重命名原始文件:

perl -e '
    for ( 
        sort { $a->[0] <=> $b->[0] } 
        map { m/(\d+)/; [$1, $_ ] } 
        grep { -f $_ && ! -l $_ } 
        @ARGV 
    ) {
        $n = --$_-> [0];

        ($newname = $_->[1]) =~ s/\A(?i)(cam)\d+(.*)\z/$1$n$2/;
        print "Executing command ===> rename $_->[1], $newname\n";
        rename $_->[1], $newname;
}' * 

假设目录的初始内容为:

cam1-vid.webm
cam13-vid.webm
cam12-vid.webm
cam11-vid.webm
cam10-vid.webm
cam2-vid.webm

运行命令后产生:

cam0-vid.webm
cam10-vid.webm
cam11-vid.webm
cam12-vid.webm
cam1-vid.webm
cam9-vid.webm