4

多数の画像ファイルのバッチ処理を必要とするプロジェクトに取り組んでいます。簡単にするために、ユーザー入力に基づいてディレクトリを作成し、nディレクトリにファイルを移動するスクリプトを作成しました。m

私の問題は、シェルスクリプトを介したディレクトリトラバーサルを理解することです。

上記の並べ替えスクリプトの最後にこのスニペットを追加しました

dirlist=$(find $1 -mindepth 1 -maxdepth 1 -type d)

for dir in $dirlist
do
  cd $dir
  echo $dir
  ls
done

Pano2フォルダー内で実行すると、2つの内部フォルダーが含まれているため、常にエラーが発生します。

./dirTravel: line 9: cd: Pano2/05-15-2012-2: No such file or directory

しかし、その後、指定したディレクトリからファイルリストを取得します。

警告の背後にある理由は何ですか?Pano2 /内のフォルダーのリストを取得したcd ../後で追加すると、ファイル自体は取得されません。ls

4

3 に答える 3

6

サブシェルを使用してディレクトリを切り替えることをお勧めします。

dirlist=$(find $1 -mindepth 1 -maxdepth 1 -type d)

for dir in $dirlist
do
  (
  cd $dir
  echo $dir
  ls
  )
done

サブシェル内のコードは親シェルに影響を与えないため、「元に戻す方法」に関する問題を発生させることなく、どこにでもディレクトリを変更できます。

これには、ディレクトリ名にスペース、改行、またはその他の予期しない扱いにくい文字が含まれている可能性がある場合、プロセス全体が困難になるという標準的な警告が伴います. 移植可能なファイル名文字セット ( ) を使用していれば[-_.A-Za-z0-9]、書かれているような問題に遭遇することはありません。

于 2012-05-16T02:06:39.933 に答える
3

私の推測では、あなたは 2 レベルの深さまで進みますが、1 レベル上に戻るだけです。cd ../..の後にa を追加するか、代わりに andをls使用してみてください。pushdpopd

例えば:

for dir in $dirlist
do
  pushd $dir
  echo $dir
  ls
  popd
done

@shellter が指摘しているように、これらのディレクトリにスペースがある場合、次のような方がうまくいく可能性があります。

find $1 -mindepth 1 -maxdepth 1 -type d | while read -r dir
do
  pushd "$dir"  # note the quotes, which encapsulate whitespace
  echo $dir
  ls
  popd
done
于 2012-05-16T01:47:09.720 に答える
2

lsコマンドを実行するためにディレクトリに cd する理由はまったくありません。以下が機能するはずです。

find "$1" -mindepth 1 -maxdepth 1 -type d -exec ls {} \;

これが単なる例であり、作業ディレクトリに依存する他のコマンドを実際に実行する場合は、bash -c を -exec と共に使用できます。

find "$1" -mindepth 1 -maxdepth 1 -type d -exec bash -c 'cd "$1"; echo "$1"; ls' -- {} \;

bash -c 呼び出しはサブシェルを生成するため、現在のシェルのディレクトリが変更されることを心配する必要はありません。

于 2012-05-16T03:06:03.953 に答える