1

Bashスクリプトを使用して、すべてのアンダースコア文字を複数のファイル名の空白に置き換えるにはどうすればよいですか?このコードを使用して、アンダースコアをダッシュ​​に置き換えることができます。しかし、それは空白でどのように機能しますか?

for i in *.mp3;
do x=$(echo $i | grep '_' | sed 's/_/\-/g');
if [ -n "$x" ];
then mv $i $x;
fi;
done;

ありがとうございました!

4

3 に答える 3

9

これは行う必要があります:

for i in *.mp3; do
    [[ "$i" = *_* ]] && mv -nv -- "$i" "${i//_/ }"
done
  • このテスト[[ "$i" = *_* ]]では、ファイル名にアンダースコアが含まれているかどうかをテストし、含まれている場合は、すべてのアンダースコアがスペースに置き換えられた場所に展開されるmvファイルをテストします(シェルパラメーターの展開を参照)。"${i//_/ }"i
  • -nmv意味するオプションno clobberは、既存のファイルを上書きしません(非常に安全です)。オプション
  • のオプション-vmvverbose:が何をしているのかを示します(何が起こっているのかを確認したい場合)。非常にオプションです
  • これ--mv、引数がここから始まることを示すためにここにあります。これは常に良い習慣です。ファイル名がで始まるかのように、それをオプションとして解釈しようとし、スクリプトが失敗するからです-非常に良い習慣です。mv

別のコメント:グロブ(つまり、for i in *.mp3)を使用する場合は、設定shopt -s nullglobまたはのいずれかを使用することをお勧めしますshopt -s failglob。前者は*.mp3パターンに一致するファイルがない場合は何も展開せず(したがってループは実行されません)、後者は明示的にエラーを発生させます。これらのオプションがないと、一致するファイル*.mp3が存在しない場合、ループ内のコードiは逐語的な値*.mp3で実行され、問題が発生する可能性があります。(まあ、ガードのおかげでここでは問題はありませんが、[[ "$i" = *_* ]]常にどちらかのオプションを使用するのは良い習慣です)。

お役に立てれば!

于 2012-12-19T18:32:52.820 に答える
2

スクリプトがスペースで失敗する理由は、に渡されたときにファイル名が複数の引数として扱われるためmvです。各ファイル名が単一のアグリメントとして扱われるように、ファイル名を引用符で囲む必要があります。スクリプトの関連する行を次のように更新します。

mv "$i" "$x"  
# where $i is your original filename, and $x is the new name

余談ですが、perlバージョンのrenameコマンドがインストールされている場合は、スクリプトをスキップして、次のコマンドを使用して同じことを実行します。

rename 's/_/ /' *.mp3

または、より古典的なrenameコマンドがある場合:

rename "_" " " *.mp3
于 2012-12-19T18:25:19.600 に答える
1

使用するtr

tr '_' ' ' <file1 >file2
于 2012-12-19T18:26:36.647 に答える