1

在我的终端上运行“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)来完成?

4

3 回答 3

6

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

for i in {1..200}
do
    mv "cam${i}-vid.webm" "cam$((i-1))-vid.webm"
done
于 2013-07-23T20:07:25.653 回答
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.webmcam01-vid.webmcam01-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
于 2013-07-23T22:11:24.477 回答
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
于 2013-07-23T20:43:15.400 回答