bash 脚本仅适用于调试

bash 脚本仅适用于调试

我正在尝试从文件名中删除字符。

文件

#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)* 是您的条目。

相关内容