web-dev-qa-db-ja.com

シェルスクリプトのすべてのサブディレクトリのスペースを削除する方法

下線付きのすべてのスペースを削除するシェルスクリプトを試してみました。

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

ディレクトリがある場合/home/user/g h/y h/u j/変更されますy hディレクトリからy_hの場合、/home/user/g h/y h/u j

No such file or directory
6
krishna

これを使って:

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

findは、名前にスペースが含まれるファイルとフォルダーを検索します。これは印刷されます(-print0)特殊ファイル名にも対処するための区切り文字としてnullbytesを使用します。

sort -rzはファイルの順序を逆にするので、フォルダ内の最も深いファイルが最初に移動し、フォルダ自体が最後になります。したがって、すべてのファイルとフォルダがその内部で名前が変更される前に、名前が変更されるフォルダはありません。

最後に、mvコマンドはファイル/フォルダーの名前を変更します。ターゲット名では、ファイルbasenameのスペースのみを削除します。そうしないと、アクセスできなくなります。

5
chaos

ファイル名basename(パスの姓)とdirnameを区切ります:

find $1 -depth -name "* *" -print0 | \
while read -d $'\0' f ; do
    a="$(dirname "$f")"
    b="$(basename "$f")"
    #optional check if the basename changes -> reduces errors in mv command
    #only needed when using -wholename instead of -name in find, so skippable
    if [ "${b// /_}" != "$b" ] ; then
      mv -v "$a"/"$b"  "$a"/"${b// /_}"
    fi
done

より高いディレクトリを変更する前に最初にサブディレクトリを変更する問題は、find-depth仕様ですでに対処されています。

0
Fiximan
find $1 -depth -name "* *" -type d -execdir rename 's/ /_/g' "{}" \;
0
neuron