1

親フォルダーのみを実行するこのスクリプトがあり、サブフォルダーとファイルの名前を変更しません-数値以外のすべてを_で削除することを望んでいます。

#!/bin/bash
for f in *
do
   new="${f// /_}"
   if [ "$new" != "$f" ]
   then
      if [ -e "$new" ]
      then
         echo not renaming \""$f"\" because \""$new"\" already exists
      else
         echo moving "$f" to "$new"
         mv "$f" "$new"
      fi
   fi
done
4

5 に答える 5

4

ファイルとディレクトリのリストを取得する:

ファイルを再帰的に操作するに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

注:英数字以外のものに対して「正しいことを行う」スクリプトを実装することは、自明ではないようです。たとえば、ファイル名またはディレクトリ名にドットや既存のアンダースコア、またはその他の「通常の」許可された文字を処理する方法がわかりません。

一般的な方法で望ましくない/特殊文字を識別することも問題です。国際言語環境ではさらに複雑になります。「英語のアルファベットの数字または文字のみを許可する」という簡単な言い方がわかりません。誰かがアイデアを持っている場合は、先に進んで回答を投稿してください。

于 2012-07-24T07:40:42.380 に答える
1

コマンドを再帰的に実行することもできます (おそらく、同じスクリプトを呼び出さずにこれを実行する方法がありますが、今は機能しません)。

このスクリプトがあなたのパスまたはここにあるとしましょう/usr/local/bin/remove_spaces.sh:

#!/bin/bash 

for f in *
do
   if [ -d "$f" ]
   then
      cd "$f"
      /usr/local/bin/remove_spaces.sh
      cd ..
   fi

   new="${f// /_}"
   if [ "$new" != "$f" ]
   then
      if [ -e "$new" ]
      then
     echo not renaming \""$f"\" because \""$new"\" already exists
      else
     echo moving "$f" to "$new"
     mv "$f" "$new"
      fi
   fi
done

したがって、現在のファイルfがディレクトリであるかどうかを本質的に確認し、そうであれば、そこに cd してコマンドを再実行し、必要に応じて cd に戻って名前を変更します。

于 2012-07-23T23:54:46.463 に答える
0

ファイル名にタブまたは改行を含めることができない場合(引用符に注意してください):

IFS="$(printf '\n\t')"
for file in $(find .) ; do
  COMMAND "$file" ...
done

シェルのファイル名とパス名も参照してください

于 2012-07-24T06:42:01.157 に答える
0

編集:申し訳ありませんが、空白を忘れていました。読み取りループである私の標準的な処理方法(ファイルの名前に改行を含めることはできないと想定しています)

find | {
read f
while [ -n "$f" ]
do
    # process "$f" (always with the quotes)
    read f
done
}
于 2012-07-23T23:33:25.170 に答える
0

最近のバージョンのbashでは、次を使用できます

for f in **

機能させるには、globstar オプションを設定する必要がある場合があります。

shopt -s globstar
于 2012-07-23T23:37:23.720 に答える