关于这个问题及解答:https://unix.stackexchange.com/a/188020/189709
for f in *; do mv --backup=numbered -- "$f" "${f,,}"; done
rename -v -- 's/\.~(\d+)~/$1/' *.~*~
mv:此命令隐式将所有文件名更改为小写。如何修改选项才能不这样做?备份编号足以区分文件。
rename: test.~1~ 如果文件 test1 已经存在,则不会重命名。如何更改选项以将 test.~1~ 重命名为 test2?
答案1
您可能希望自己实现重命名策略,因为您正在查看的代码在调用中显式小写文件名以mv
捕获实际文件名冲突中的重复项。
以下仅在存在冲突时重命名文件,而不会实际引起冲突(即,它不会回退到 GNUmv
来处理冲突):
#!/bin/bash
# The suffix array contains a filename suffix (a positive integer)
# for each lower-cased filename.
declare -A suffix
# Get all names in the current directory.
set -- *
# Initialise the suffixes for each existing name to zero.
for name do
suffix[${name,,}]=0
done
for name do
# Loop until no name collision.
while true; do
# Get the current suffix for this filename.
suf=${suffix[${name,,}]}
# Increment the suffix for this filename.
suffix[${name,,}]=$(( ${suffix[${name,,}]} + 1 ))
# If the suffix is 0, empty it.
[[ $suf == 0 ]] && suf=
# Create the new name.
newname=$name$suf
# Break out of the loop if the name didn't change, or if
# there's no other file that has this name.
if [[ $name == "$newname" ]] ||
[[ -z ${suffix[${newname,,}]} ]]
then
break
fi
done
if [[ $name != "$newname" ]]; then
printf '%s --> %s\n' "$name" "$newname"
# uncomment the next line to actually do the renaming
# mv -- "$name" "$newname"
else
printf '%s unchanged\n' "$name"
fi
done
(请注意注释掉的部分mv
,您可能希望在注释掉该行的情况下运行它,直到您确信它做了正确的事情)
测试:
$ ls
A Bb TEST1 a bb test
BB TEST Test bB script.sh
$ bash script.sh
A unchanged
BB unchanged
Bb --> Bb1
TEST unchanged
TEST1 unchanged
Test --> Test2
a --> a1
bB --> bB2
bb --> bb3
script.sh unchanged
test --> test3