ファイルとディレクトリのリストを取得する:
ファイルを再帰的に操作するにfind
は、グロブに比べて使用する方が優れたソリューションです。操作を開始する前に、bash 配列にファイル名を入力することをお勧めします。また、これを一度に1ステップずつ、ディレクトリの次にファイルにするのが賢明だと思います。ディレクトリの名前を変更したくないのに、後でファイルの名前を変更しているときに、ファイルが存在しないことがわかります。同じ理由で、スクリプトがファイルシステム階層のより深いレベルで機能することも重要です (したがって、以下を使用しsort
ます)。
リストの操作:
リストを取得したら、共通のシェル関数を呼び出して、ファイルまたはディレクトリ名の正規化と名前変更を行うことができます。必要なものを取得するには、名前を適切に引用することが重要であることに注意してください。コマンド ラインを解析する際に、bash (またはその他のシェル) が単語の境界としてスペースを使用するため、これは非常に重要です。
スクリプト:
次のスクリプト (以下./rename_spaces.bash
の出力例で名前が付けられています) は、必要な処理を実行する必要があります。独自の変な文字を追加するには、それらをweirdchars
変数に追加します。必要に応じて文字をエスケープする必要があることに注意してください (たとえば、一重引用符がエスケープされています)。新しいファイル名が存在する場合、スクリプトはメッセージをスキップしてスキップします。これはまた、単純な名前変更 (元の名前に奇妙な文字が含まれていないファイル名) のメッセージを出力することも意味します。これは一部の人にとっては迷惑かもしれません (例:私 :-p)
#!/bin/bash
# set -o xtrace # uncomment for debugging
declare weirdchars=" &\'"
function normalise_and_rename() {
declare -a list=("${!1}")
for fileordir in "${list[@]}";
do
newname="${fileordir//[${weirdchars}]/_}"
[[ ! -a "$newname" ]] && \
mv "$fileordir" "$newname" || \
echo "Skipping existing file, $newname."
done
}
declare -a dirs files
while IFS= read -r -d '' dir; do
dirs+=("$dir")
done < <(find -type d -print0 | sort -z)
normalise_and_rename dirs[@]
while IFS= read -r -d '' file; do
files+=("$file")
done < <(find -type f -print0 | sort -z)
normalise_and_rename files[@]
上記のスクリプトを実行する前と実行した後の、名前にスペースが含まれるディレクトリとファイルを含むディレクトリ ツリーの出力例を次に示します。
$ tree
.
├── dir1
│ ├── subdir1\ with\ spaces
│ │ └── file1
│ └── subdir2\ with\ spaces&weird\ chars'
│ └── file2
├── dir2
│ ├── subdir1\ with\ spaces
│ │ └── file1\ with\ space
│ └── subdir2\ with\ spaces
│ └── file2\ with\ space
├── dir3
│ ├── subdir1
│ │ └── file1
│ ├── subdir2
│ │ └── file2
│ └── subdir3
│ └── file3
└── rename_spaces.bash
10 directories, 8 files
$ ./rename_spaces.bash
$ tree
.
├── dir1
│ ├── subdir1_with_spaces
│ │ └── file1
│ └── subdir2_with_spaces_weird_chars_
│ └── file2
├── dir2
│ ├── subdir1_with_spaces
│ │ └── file1_with_space
│ └── subdir2_with_spaces
│ └── file2_with_space
├── dir3
│ ├── subdir1
│ │ └── file1
│ ├── subdir2
│ │ └── file2
│ └── subdir3
│ └── file3
└── rename_spaces.bash
10 directories, 8 files
注:英数字以外のものに対して「正しいことを行う」スクリプトを実装することは、自明ではないようです。たとえば、ファイル名またはディレクトリ名にドットや既存のアンダースコア、またはその他の「通常の」許可された文字を処理する方法がわかりません。
一般的な方法で望ましくない/特殊文字を識別することも問題です。国際言語環境ではさらに複雑になります。「英語のアルファベットの数字または文字のみを許可する」という簡単な言い方がわかりません。誰かがアイデアを持っている場合は、先に進んで回答を投稿してください。