web-dev-qa-db-ja.com

ファイルの名前を変更するときにスペースを置き換えないでください

私はこのようなファイルの名前を変更しようとしています:

for file in *;
do
mv -i "$file" "$(echo "$file" | sed -e 's/[^A-Za-z0-9._-]/_/g')";
done

ただし、sedコマンドは、すべてのスペースを_に置き換えます。

sedコマンドを編集して、指定した文字とともにスペースを含めるにはどうすればよいですか? \sを使用しようとしましたが、機能しません...

編集:
たとえば、ファイルtrip: hillの名前はtrip_ hillに変更する必要がありますが、上記のコマンドではtrip__hillになります。

10
user679568

sedでファイル名を解析しないでください! echo "$file"の出力は信頼できない場合があります。

renameを使用します。 17.10では、最初にインストールする必要があります

Sudo apt install rename

次に:

rename -n -- 's/[^-A-Za-z0-9_ .]/_/g' *

ノート

  • 実際にファイルの名前を変更するためにテストした後、-nを削除します
  • --ファイルの先頭が-の場合のオプションの終わり
  • 置き換えたくない[^-A-Za-z0-9_ .]文字--を最初または最後に配置して、範囲を示すことができないようにします(文字どおりこれらの位置で処理されます)。
  • クラスにスペースを含めることができます
  • .リテラルとして扱われます (他の正規表現コンテキストでは、任意の文字を表し、エスケープする必要があります)。

これはsedでも機能します:

$ echo 'trip: hill' | sed 's/[^-A-Za-z0-9 _.]/_/g'
trip_ hill

バージョンの最後にスペースを追加すると、エラーが発生します。

$ echo 'trip: hill' | sed -e 's/[^A-Za-z0-9._- ]/_/g'
sed: -e expression #1, char 22: Invalid range end

しかし、最後に-を使用すると、動作します:

$ echo 'trip: hill' | sed -e 's/[^A-Za-z0-9._ -]/_/g'
trip_ hill

そのため、スペースを追加したときに、ハイフンの位置が問題を引き起こした可能性があります。ただし、ファイル名を解析しないことをお勧めします!

11
Zanna

また、単にシェルを使用することもできます。 Bashのパラメーター展開 は置換を実行できます。

for f in ./* ; do
    mv "$f" "${f//[^-A-Za-z0-9._ ]/_}"
done

ダブルスラッシュは、それ以外のすべての一致を置き換えるように指示しますが、それ以外の構文は簡単です。

2
ilkkachu