问题描述
我有大量文件,格式为x00000.jpg
,X00000.jpg
和xx00000.jpg
。
如何重命名这些文件,使它们都是大写的,忽略名称的数字部分?
最佳解决思路
for f in * ; do mv -- "$f" "$(tr [:lower:] [:upper:] <<< "$f")" ; done
次佳解决思路
您不能仅从Bash重命名文件,因为Bash没有任何用于重命名文件的内置命令。您必须至少使用一个外部命令。
如果允许Perl:
perl -e 'for(@ARGV){rename$_,uc}' *.jpg
如果允许Python:
python -c 'import os, sys; [os.rename(a, a.upper()) for a in sys.argv[1:]]' *.jpg
如果您有数千或更多文件,则上述解决方案速度很快,以下解决方案速度明显较慢。
如果允许AWK,ls
和mv
:
# Insecure if the filenames contain an apostrophe or newline!
eval "$(ls -- *.jpg | awk '{print"mv -- \x27"$0"\x27 \x27"toupper($0)"\x27"}')"
如果您有大量文件,则上述解决方案不起作用,因为*.jpg
扩展为太长的参数列表(错误:参数列表太长)。
如果允许tr
和mv
,请参阅damienfrancois的回答。
如果允许mv
:
for file in *; do mv -- "$file" "${file^^}"; done
请注意,它们最后将.jpg
重命名为.JPG
,但您可以修改它们以避免这种情况。
第三种解决思路
bash
shell具有将变量名称转换为all-caps的语法。
for file in * ; do # or *.jpg, or x*.jpg, or whatever
mv $file ${file^^}
done
我认为这可能是一个相当新的功能,因此首先要验证您的bash
版本是否实现了它。为避免错误,请尝试用echo mv
替换mv
,以确保它能够满足您的需求。
此功能的文档是here,或者键入info bash
并搜索”upper”。
如果目标文件已经存在(例如,如果x00000.jpg
和X00000.JPG
都已存在),您应该决定该怎么做,除非您确定它不是问题。要检测此类名称冲突,您可以尝试:
ls *.txt | tr '[a-z]' '[A-Z]' | sort | uniq -c | sort -n
并查找任何不以1
开头的行。
第四种思路
结合之前的答案可以产生:
for file in * ; do # or *.jpg, or x*.jpg, or whatever
basename=$(tr '[:lower:]' '[:upper:]' <<< "${file%.*}")
newname="$basename.${file#*.}"
mv "$file" "$newname"
done
第五种思路
使用tr:
f="x00000.jpg"
n="${f%.*}"
n=$(tr '[:lower:]' '[:upper:]' <<< "$n")
f="$n.${f#*.}"
echo "$f"
OUTPUT:
X00000.jpg
第六种思路
rename
可能最简单的方法是rename
多个文件。要将小写名称转换为高位,您需要:
rename 'y/a-z/A-Z/' *