オプションの角かっこ引数を使用して検索

オプションの角かっこ引数を使用して検索

クエリにオプションのグループ化パラメータリストを追加するには?

たとえば、デフォルトのパラメーター配列を使用して、指定された他の変数条件に関係なく常に検索されるファイルを定義します。

# args to find any files ending _count or _scan

._. fargs=( -type f -name '*_count' -o -name '*_scan' )
._. cd /sys/fs/ext4/sda1
._. find . \( "${fargs[@]}" \) 2> /dev/null
./mb_min_to_scan
./errors_count
./mb_max_to_scan
./msg_count
./warning_count

オプションの追加パラメータの追加

._. fpterm=warning
._. fpterm2=max
._. fANDargs=( -ipath "*$fpterm*" -o -ipath "*$fpterm2*" )

(aまたはbまたはc)および(dまたはeまたはf)の形式で検索を実行するには、括弧内のオプションのパラメータを使用します。

._. find . \( "${fargs[@]}" \) \( "${fANDargs[@]}" \) 2> /dev/null
./dm-1/mb_max_to_scan
./dm-1/warning_count
./dm-0/mb_max_to_scan
./dm-0/warning_count
./sda1/mb_max_to_scan
./sda1/warning_count

ただし、オプションの arg 配列が空の場合、他の条件が満たされなくなり、ファイルがまったく見つかりません。

._. fANDargs=()
._. find . \( "${fargs[@]}" \) \( "${fANDargs[@]}" \) 2> /dev/null
._. 

空の括弧は問題を引き起こす可能性があります。

._. find . \( "${fargs[@]}" \) \( \) 2> /dev/null
._.

しかし、通常、空のarg配列は他の条件が満たされるのを妨げません。

._. fANDargs=()   
._. echo "${fANDargs[@]}"

._. find . \( "${fargs[@]}" \) "${fANDargs[@]}" 2> /dev/null
...
./sda1/mb_min_to_scan
./sda1/errors_count
./sda1/mb_max_to_scan
./sda1/msg_count
./sda1/warning_count

したがって、オプションのargs配列が空でない場合にのみ括弧を追加できる場合は、このコマンドを使用できます。

しかし、条件付きで括弧を追加する方法は?

次のように配列に括弧を追加するとうまくいきません。

._. fpterm=warning
._. fANDargs=()
._. [ ! -z $fpterm ] && fANDargs+=( '\(' -ipath "*$fpterm*" '\)' )
._. echo "${fANDargs[@]}"
\( -ipath *warning* \)
._. find . \( "${fargs[@]}" \) "${fANDargs[@]}" 2> /dev/null
._.

答え1

[ ! -z $fpterm ] && fANDargs+=( '\(' -ipath "*$fpterm*" '\)' )

ここに二重引用符があります。レイヤーを1つだけ試してください。

fANDargs+=( \(  -ipath "*$fpterm*" \)  )   # or  
fANDargs+=( '(' -ipath "*$fpterm*" ')' )   # or with "(" and ")"

(また引用符を使用する必要があります[ ! -z "$fpterm" ]

通常、コマンドで直接単語を使用するのと同じ方法で、配列の割り当てに単語を使用します。"${array[@]}"あなたのように引用符を使用すると、配列の内容が拡張されます。追加の変更は必要ありません。

(これは人々がよく理解していない部分です。彼らはシェルが拡張結果の引用符を処理すると期待しているようです。そうではありません。ここでは「一般的な」プログラミング言語に近いです。引用符を使用して削除します。 +グローブの問題。)

もちろんここでの文脈は、それfind自体で見たいのは、角括弧をあるまま(他の引数で)あるということです。引用符を見る必要はありませんが、見る必要はあります。シェル括弧はシェル構文の一部である特殊文字であるため必要です。したがって、引用符なしで使用できますが、somecmd { foo bar }で使用する必要がありますsomecmd \( foo bar \)


ところで、GNU findは空の括弧セットについて警告します。

$ find . \( \)
find: invalid expression; empty parentheses are not allowed.

そして論理的に言えば、とにかく奇妙に見えます。私の最初の本能は、空の角括弧をfalseと評価する必要があり、それがfind \( whatever \) \( \)常に矛盾を引き起こすことです。ただし、これはBusyboxが実行するようにtrueと解釈される可能性がbusybox find . \( \) -name '*.txt'ありますbusybox find . -name '*.txt'

関連情報