我正在尝试从文件名中删除字符。
文件
#ls
Peter, Paul & Mary - The Very Best of Peter, Paul and Mary (AutoFlac).flac
Peter, Paul & Mary - The Very Best of Peter, Paul and Mary (AutoFlac).log
Peter, Paul & Mary - The Very Best of Peter, Paul and Mary.cue
我想要的输出是:
#ls
Peter, Paul & Mary - The Very Best of Peter, Paul and Mary.cue
Peter, Paul & Mary - The Very Best of Peter, Paul and Mary.flac
Peter, Paul & Mary - The Very Best of Peter, Paul and Mary.log
脚本
#!/bin/bash
SUFFIX="(AutoFLAC)"
#search directory for file with a suffix of (AutoFLAC)
for entry in *$SUFFIX*
do
#remove a leading space and (AutoFLAC) from the file name
FILENAME=`echo $entry | sed 's/ (AutoFLAC)//'`
echo "$entry"
echo "$FILENAME"
#change the old file name for the new file name
mv "$entry" "$FILENAME"
done
如果我添加-x
,它就会起作用。
Mac-Attack:edit-file-names $ ./edit-file-names1.sh
+ SUFFIX='(AutoFLAC)'
+ for entry in '*$SUFFIX*'
++ echo Peter, Paul '&' Mary - The Very Best of Peter, Paul and Mary '(AutoFLAC).flac'
++ sed 's/ (AutoFLAC)//'
+ FILENAME='Peter, Paul & Mary - The Very Best of Peter, Paul and Mary.flac'
+ echo 'Peter, Paul & Mary - The Very Best of Peter, Paul and Mary (AutoFLAC).flac'
Peter, Paul & Mary - The Very Best of Peter, Paul and Mary (AutoFLAC).flac
+ echo 'Peter, Paul & Mary - The Very Best of Peter, Paul and Mary.flac'
Peter, Paul & Mary - The Very Best of Peter, Paul and Mary.flac
+ mv 'Peter, Paul & Mary - The Very Best of Peter, Paul and Mary (AutoFLAC).flac'
'Peter, Paul & Mary - The Very Best of Peter, Paul and Mary.flac'
+ for entry in '*$SUFFIX*'
++ echo Peter, Paul '&' Mary - The Very Best of Peter, Paul and Mary '(AutoFLAC).log'
++ sed 's/ (AutoFLAC)//'
+ FILENAME='Peter, Paul & Mary - The Very Best of Peter, Paul and Mary.log'
+ echo 'Peter, Paul & Mary - The Very Best of Peter, Paul and Mary (AutoFLAC).log'
Peter, Paul & Mary - The Very Best of Peter, Paul and Mary (AutoFLAC).log
+ echo 'Peter, Paul & Mary - The Very Best of Peter, Paul and Mary.log'
Peter, Paul & Mary - The Very Best of Peter, Paul and Mary.log
+ mv 'Peter, Paul & Mary - The Very Best of Peter, Paul and Mary (AutoFLAC).log' 'Peter, Paul & Mary - The Very Best of Peter, Paul and Mary.log'
Mac-Attack:edit-file-names $ ls
Peter, Paul & Mary - The Very Best of Peter, Paul and Mary.cue
Peter, Paul & Mary - The Very Best of Peter, Paul and Mary.flac
Peter, Paul & Mary - The Very Best of Peter, Paul and Mary.log
没有-x
:
Mac-Attack:edit-file-names $ ./edit-file-names2.sh
*(AutoFLAC)*
*(AutoFLAC)*
mv: rename *(AutoFLAC)* to *(AutoFLAC)*: No such file or directory
见解、想法?
答案1
不区分大小写的通配符匹配显然存在一些奇怪的情况。根据ls
输出,文件名包含(AutoFlac)
,而您的脚本查找(AutoFLAC)
.传统上,Unix 工具仅当两个文件名逐字节相同时才认为它们是相同的。没有内置任何不区分大小写的匹配。 Bash 似乎在不区分大小写的文件系统上表现不一致,这可能是一个错误。
如果您在变量替换周围使用双引号,您的脚本将会更加健壮。如果不这样做,bash(像其他 shell 一样)会对变量替换的结果执行通配。这可能是您麻烦的根源。始终在变量替换和命令替换两边加上双引号:"$foo"
,"$(foo)"
除非您知道要对结果执行分词和通配符。此外,缺少双引号的脚本不适用于某些文件名,例如,空白序列不是单个空格。
我还建议在 shell 内进行文本替换,这样可以降低损坏文件名的风险。
SUFFIX="(AutoFlac)"
for entry in *"$SUFFIX"*; do
target=${entry/ $SUFFIX/}
mv -- "$entry" "$target"
done
无法强制不区分大小写的通配符匹配,但您可以通过执行自己的匹配使脚本忽略大小写。
SUFFIX="(autoflac)"
for entry in *; do
if [[ ${entry,,} = *$SUFFIX* ]]; then
# Remove everything from the last space to the last .
mv -- "$entry" "${entry% *}.${entry##*.}"
fi
done
答案2
如果 shell 找不到与 glob 模式匹配的文件,它将在 glob 模式完好无损的情况下运行一次循环。由于此行为,*(AutoFLAC)* 是您的条目。