bash:截断文件名,为重复项添加递增数字

bash: Truncate filenames, adding incrementing number for duplicates

我想缩短给定位置的所有文件名,在截断产生重复的地方,在文件名中包含一个递增的数字。多亏了这个解决方案,我大部分时间都在那里:bash: Truncate Filenames, keeping them unique

我做了一个小修改,允许它涵盖多个文件扩展名(因为原始文件只是为 jpeg 编写的)。我的脚本:

num=1
length=8
for file in *
do
    newname=$file
    extension=${file: -4}
    until [[ ! -f $newname ]]
    do
        (( sublen = length - ${#num} ))
        printf -v newname '%.*s%d' "$sublen" "$file" "$num"
        (( num++ ))
    done
    mv "$file" "$newname""$extension"
done

原文件列表:

DumbFilename.txt
DumbFilename2.txt
DumbFilename3.txt
GrossFilename.txt
GrossFilename2.txt
GrossFilename3.txt
LongFilename.doc
LongFilename2.doc
LongFilename3.doc
UglyFilename.doc
UglyFilename2.doc
UglyFilename3.doc

以上代码的输出:

DumbFil1.txt
DumbFil2.txt
DumbFil3.txt
GrossFi4.txt
GrossFi5.txt
GrossFi6.txt
LongFil7.doc
LongFil8.doc
LongFil9.doc
UglyFi10.doc
UglyFi11.doc
UglyFi12.doc

我唯一的问题是数字在一个长序列中递增。我只希望它为重复的每个实例递增,如下所示:

DumbFil1.txt
DumbFil2.txt
DumbFil3.txt
GrossFi1.txt
GrossFi2.txt
GrossFi3.txt
LongFil1.doc
LongFil2.doc
LongFil3.doc
UglyFil1.doc
UglyFil2.doc
UglyFil3.doc

我该怎么做?

将截断的文件名放在一个变量中。在下一次迭代中,检查当前截断的文件名是否与前一个相同。如果不同,将 num 重置为 1 以重新开始序列。

length=8
num=1
last_truncated=
for file in *
do
    newname=$file
    extension=${file: -4}
    until [[ ! -f $newname ]]
    do
        (( sublen = length - ${#num} ))
        truncated=${newname:0:$sublen}
        # reset $num with new prefix
        if [[ $truncated != $last_truncated ]]
        then num=1
        fi
        newname=$truncated$num
        (( num++ ))
    done
    last_truncated=truncated
    mv "$file" "$newname""$extension"
done

请您尝试以下操作:

length=8
for file in *; do
    newname=$file
    extension=${file: -4}
    for (( num=1; ; num++ )); do
        (( sublen = length - ${#num} ))
        printf -v newname '%.*s%d%s' "$sublen" "$file" "$num" "$extension"
        [[ ! -f $newname ]] && break
    done
    mv -- "$file" "$newname"
done

顺便说一句,您的原始脚本会检查 $newname 是否存在 附加扩展名,这在某些情况下会中断。