web-dev-qa-db-ja.com

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

すべての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

xy z.xmlという名前の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
20
krishna

これをbashで使用します。

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

findは、名前にスペースが含まれるファイルを検索します。ファイル名はnullbyte(-print0)デリミタとして使用し、特別なファイル名にも対応します。次に、readビルトインがnullバイトで区切られたファイル名を読み取り、最後にmvがスペースをアンダースコアに置き換えます。

編集:ディレクトリのスペースも削除したい場合は、もう少し複雑です。ディレクトリの名前が変更され、findが検出した名前でアクセスできなくなります。これを試して:

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

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

32
chaos
  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// /_}"' {} \;
    
21
A.B.

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

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

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

2
NekoMisaki

renameを使用:

rename 's/\s/_/g' ./*.xml

findは必要ありません:)

1
Jan Werkhoven