デバッグ専用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 ツールは、バイト単位で同じ 2 つのファイル名だけが同じと見なされていました。大文字と小文字を区別する一致機能は組み込まれていません。 Bashは大文字と小文字を区別しないファイルシステムで一貫して動作しないように見えます。これはバグかもしれません。

変数の置換に二重引用符を使用すると、スクリプトがより強力になります。そうしないと、bash(他のシェルと同様)は変数置換の結果にワイルドカードを実行します。これが問題の原因である可能性があります。変数置換とコマンド置換は常に二重引用符で囲みます"$foo""$(foo)"結果に対してトークン化とワイルドカードを実行したい場合を除きます。また、二重引用符がないスクリプトは、単一のスペースの代わりにスペースシーケンスなどの特定のファイル名では機能しません。

また、ファイル名が破損する危険性を減らすために、シェル内でテキストの置き換えを実行することをお勧めします。

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

シェルがglobパターンと一致するファイルを見つけることができない場合は、globパターンをそのまま維持しながらループを実行します。この動作により、*(AutoFLAC)*はエントリです。

関連情報