すべてのディレクトリとファイルの名前を変更し、スペースを削除するスクリプトがあります。再帰的に実行されます。
#!/bin/bash
find -name "* *" -print0 | sort -rz | \
while read -d $'\0' f; do mv -v "$f" "$(dirname "$f")/$(basename "${f// /_}")"; done
~
スクリプトをディレクトリから実行すると、次のプロジェクトの名前が予期せず変更されました。
./.cache/google-chrome/Default/Storage/ext/nmmhkkegccagdldgiimedpiccmgmieda/def/Code Cache
./.cache/google-chrome/Default/Storage/ext/gfdkimpbcpahaombhbimeihdjnejgicl/def/Code Cache
./.cache/google-chrome/Default/Code Cache
.
私のスクリプトから名前の変更で始まるすべてのディレクトリまたはファイルを除外したいと思います。このようなスクリプトをどのように書きますか?この目的のために正規表現を使用する必要がありますか?
ベストアンサー1
パイプラインの他のコマンドを見過ごすことなく、find
隠された名前のディレクトリを入力する必要はありません。
find . ! -path . -name '.*' -prune -o -name '* *' -print0 | ...
これにより、ディレクトリ(現在のディレクトリ)を除き、.
検索ツリーから名前で始まるすべてのディレクトリが削除されます。.
また、もはや隠された名前は見つかりません。
コードの残りの部分を見た後rename
(Perlバリアント)を使用することをお勧めします。
find . ! -path . -name '.*' -prune \
-o -type f -name '* *' -execdir rename -n -v 'tr/ /_/' {} \;
スペースを含むファイル名を検索し、隠された名前を無視して隠しディレクトリを入力せずにスペースをアンダースコアに置き換えます。
rename
-n
実際に何もしないようにユーティリティを呼び出します(「テスト実行」です)。-n
正しい作業を行っていると確信している場合は、削除してください。
そうでない場合は、rename
次のことを行います。
find . ! -path . -name '.*' -prune \
-o -type f -name '* *' -exec bash -c '
for pathname do
filename=${pathname##*/}
echo mv "$pathname" "${pathname%/*}/${filename// /_}"
done' bash {} +
つまり、bash
見つかった名前を繰り返してスペースをアンダースコアに変更して、名前を変更するインラインスクリプトを呼び出します。
echo
それが正しいことであることを確信したら削除しなさい。