我正在尝试编写一个将所有文件名转换为小写的bash脚本,但我遇到了问题,因为它不适用于一个案例。
当您拥有file1
和FILE1
时,您将在FILE1
上使用它,它将替换字母file1。
#!/bin/bash
testFILE=""
FLAG="1"
for FILE in *
do
testFILE=`echo FILE | tr '[A-Z]' '[a-z]'`
for FILE2 in *
do
if [ `echo $testFILE` = `echo $FILE2` ]
then
FLAG="0"
fi
done
if [ $FLAG = "1" ]
then
mv $FILE `echo $FILE | tr '[A-Z]' '[a-z]'`
fi
FLAG="1"
done
答案 0 :(得分:4)
看起来像
testFILE=`echo FILE | tr '[A-Z]' '[a-z]'`
应该是
testFILE=`echo "$FILE" | tr '[A-Z]' '[a-z]'`
重写脚本以修复其他一些小问题
#!/bin/bash
testFILE=
FLAG=1
for FILE in *; do
testFILE=$(tr '[A-Z]' '[a-z]' <<< "$FILE")
for FILE2 in *; do
if [ "$testFILE" = "$FILE2" ]; then
FLAG=0
fi
done
if [ $FLAG -eq 1 ]; then
mv -- "$FILE" "$(tr '[A-Z]' '[a-z]' <<< "$FILE")"
fi
FLAG=1
done
"$FILE"
而不是$FILE
)$()
代替波浪--
分隔接受它的命令中的参数(以防止将-file
等文件视为选项)<<<
)在这里并不重要,但<<<
稍快一些,通常更安全。 虽然更简单,但我认为你想要
#!/bin/bash
for file in *; do
testFile=$(tr '[A-Z]' '[a-z]' <<< "$file")
[ -e "$testFile" ] || mv -- "$file" "$testFile"
done
或大多数现代mv
实施(不是技术上的posix)
#!/bin/bash
for file in *; do
mv -n -- "$file" "$(tr '[A-Z]' '[a-z]' <<< "$file")"
done
来自man
页面
-n, --no-clobber
do not overwrite an existing file
答案 1 :(得分:0)
脚本下方:
find . -mindepth 1 -maxdepth 1 -print0 | while read -d '' filename
do
if [ -e ${filename,,} ]
then
mv --backup ${filename} ${filename,,} 2>/dev/null
# create a backup of the desination only if the destination already exist
# suppressing the error caused by moving the file to itself
else
mv ${filename} ${filename,,}
fi
done
可能会为你完成这项工作。
此脚本的优点