Linuxでシェルスクリプトを使用してすべてのファイル名のスペースをアンダースコアに置き換える方法は?


16

すべてのXMLファイル名のスペースを置き換えるシェルスクリプトを試してみました

for xml_file in $(find $1 -name "* .xml" -type f);
do
 echo "removing spaces from XML file:" $xml_file
 mv "$xml_file" "${xml_file// /_}";
done

という名前のxmlファイルがありxy z.xml、次のようになっているとします。

removing spaces from XML file: /home/krishna/test/xy
mv: cannot stat `/home/krishna/test/xy': No such file or directory
removing spaces from XML file: .xml
mv: cannot stat `z.xml': No such file or directory

回答:


26

これをbash以下で使用します。

find $1 -name "* *.xml" -type f -print0 | \
  while read -d $'\0' f; do mv -v "$f" "${f// /_}"; done

find名前にスペースが含まれるファイルを検索します。ファイル名は-print0、特殊なファイル名にも対応するために、区切り文字としてヌルバイト()で印刷されます。次に、readビルトインはヌルバイトで区切られたファイル名を読み取り、最後mvにスペースをアンダースコアに置き換えます。

編集:ディレクトリ内のスペースも削除したい場合は、もう少し複雑です。ディレクトリの名前を変更し、名前によって、その後もはやアクセスされていませんfind発見。これを試して:

find -name "* *" -print0 | sort -rz | \
  while read -d $'\0' f; do mv -v "$f" "$(dirname "$f")/$(basename "${f// /_}")"; done

これsort -rzにより、ファイルの順序が逆になり、フォルダー内の最も深いファイルが最初に移動し、フォルダー自体が最後に移動します。そのため、すべてのファイルとフォルダーの名前が変更される前に、フォルダーの名前が変更されることはありません。mvループ内のコマンドも少し変更されています。ターゲット名では、ファイルのベース名のスペースのみを削除します。削除しないとアクセスできません。


すべてのディレクトリでスペースをアンダースコアに置き換えようとしていますが、名前を変更した後にそのディレクトリにアクセスできないため、エラーが発生しています。
クリシュナ

@krishna回答に編集を追加しました。
カオス

1
すごい@chaos、ちょうど2つのシステムでこれらの2を実行し、それが魅力のように働いていた、いくつかのファイルおよびdirsには通過つもりはないが、それはほんの数だ
somethingSomething

macOSでは、-nameオプションの前にfindコマンドでディレクトリを指定する必要があります find . -name "* *" -print0 | sort -rz | \ while read -d $'\0' f; do mv -v "$f" "$(dirname "$f")/$(basename "${f// /_}")"; done
Laszlo Pinter

16
  1. を使用して rename

    find . -type f -name "* *.xml" -exec rename "s/\s/_/g" {} \;

    またはと $1

    find "$1" -type f -name "* *.xml" -exec rename "s/\s/_/g" {} \;
  2. を使用して mv

    find . -type f -name "* *.xml" -exec bash -c 'mv "$0" "${0// /_}"' {} \;

    またはと $1

    find "$1" -type f -name "* *.xml" -exec bash -c 'mv "$0" "${0// /_}"' {} \;

理由はわかりませんが、指定されたコマンドが機能していません。エラーと出力は表示されません。
クリシュナ

@krishna修正、申し訳ありません
AB

1
名前の変更は私のために働いた。フィストバンプ!
ブライアンピアース

1

これは私が同じ問題に直面したときに見つけた方法です:

for f in *; do mv "$f" `echo $f | tr ' ' '_'`; done

SSL証明書を自動的に更新するbashスクリプトファイルを作成していました。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.