2

Android ソース ディレクトリを解析しようとしていますが、特定のパターンを除くすべてのディレクトリ名を抽出する必要があります。以下に気がついた場合は、今のところ、除外リストに 1 つのディレクトリのみを含めましたが、さらに追加する予定です。

find コマンドは、「docs」という名前のディレクトリを除外しません。

コメントアウトされた行は機能しますが、他の行は機能しません。デバッグを簡単にするために、後で削除する min と maxdepth を含めました。

機能しない理由についてのコメントやヒントはありますか?

#! /bin/bash
ANDROID_PATH=$1
root=/
EXCLUDES=( doc )
cd ${root}
for dir in "${EXCLUDES[@]}"; do
    exclude_name_cmd_string=${exclude_name_cmd_string}$(echo \
                            "-not -name \"${dir}*\" -prune")
done
echo -e ${exclude_name_cmd_string}
custom_find_cmd=$(find ${ANDROID_PATH} -mindepth 1 -maxdepth 1 \
                    ${exclude_name_cmd_string} -type d)
#custom_find_cmd=$(find ${ANDROID_PATH} -mindepth 1 -maxdepth 1 \
#                    -not -name "doc*" -prune -type d)
echo ${custom_find_cmd} 
4

3 に答える 3

4

引用符で囲まれている可能性のある引数を使用してコマンド文字列を構築することは、悪い考えです。ネストされた引用レベルとeval、その他の危険/混乱する構文の束に入ります。

配列を使用してfind; すでにEXCLUDESを1つにしています。

また、繰り返され、私には奇妙-not-prune思えます。私はあなたのコマンドを次のように書きます:

excludes=()

for dir in "${EXCLUDES[@]}"; do
  excludes+=(-name "${dir}*" -prune -o) 
done

find "${ANDROID_PATH}" -mindepth 1 -maxdepth 1 "${excludes[@]}" -type d -print

つまり、シェルの展開によって返されるファイルのリストや、リテラルの引用符を含む文字列ではなく、展開されるリテラルのワイルドカードとして引数を-name渡す必要があります。コマンドを文字列として構築しようとすると、これを行うのは非常に困難ですが、配列を使用する場合は簡単です。findfind

友人は、友人がシェル コマンドを文字列として作成することを許可しません。

于 2012-10-21T00:38:23.710 に答える
1

あなたのスクリプト(という名前fin.sh)を次のように実行すると:

bash -x fin.sh $HOME/tmp

トレース出力の行の 1 つを次に示します。

find /Users/jleffler/tmp -mindepth 1 -maxdepth 1 -not -name '"doc*"' -prune -type d

二重引用符を一重引用符で囲んでいますか? 役に立とbashうとするものです。あなたの「機能しない」問題はdoc*、出力にディレクトリが含まれていることだと思います。それ以外は、私にはうまくいくようです。

それを修正する方法は?

...それを修正する方法を見つけたようです... Bourne シェルでそれを信頼できるかどうかはわかりません (ただし、Korn シェルは Bash と一致しているようです)。バッシュで。これは過去 30 年ほどの間に変化したものであると確信していますが、それを証明するのは困難です。古いコードを手に入れるのは簡単ではありません。

-pruneまた、除外されたディレクトリを繰り返した場合、オプションを繰り返す必要があるかどうかも疑問です。私は確かに十分に精通し-pruneていません。

于 2012-10-21T00:33:31.780 に答える
0

問題が見つかりました。そのexclude_name_cmd_stringのエスケープシーケンス。正しい構文は

exclude_name_cmd_string=${exclude_name_cmd_string}$(echo \
                        "-not -name ${dir}* -prune")
于 2012-10-21T00:29:13.293 に答える