複数のオプションにグループ化括弧はいつ必要ですか?

複数のオプションにグループ化括弧はいつ必要ですか?

私は使用しfindgrepコマンドします。

複数のオプションを連結するためにフラグと一緒に「or」を使用する必要がある場合、グループ化括弧を使用する必要がある場合、およびグループ化括弧を使用しない場合については-o非常に混乱しています。

使用時にfindグループ化括弧が必要と思われます。

find $fdir ( -name *.texi -o -name *.org )

を使用するときは、grepグループ化括弧を使用しないでください。

grep --include "*.texi" --exclude "*.org"

答え1

括弧を含むほとんどのプログラムは、grep括弧をパラメータとして具体的に処理しません。これにより:

grep "(" --include "*.texi" --exclude "*.org" ")"

grep(最初の項目を検索するパターンとして処理し、最後の項目を)ファイル名として処理します。(*)fooまるで同じようにbar。したがって、オプションをにグループ化することはできませんgrep


しかし、問題は次のとおりです。-name-typeなど-o(そうではありません。オプション到着するfind。シンボリックリンクの処理に影響を与える-P//-Hなどのいくつかのオプションが必要-Lですが、これはオプションではありません。代わりに(**)に固有の検索式の一部ですfind

強調する表現するそこに。find式を提供すると、( -name *.texi -o -name *.org )Cに似た式に近づきます。

( patternmatch(filename, "*.texi") || patternmatch(filename, "*.texi") )

何よりも。そして、find見えるすべてのファイルに対してその式を評価します。たとえば、次のような場合があります。

( -name *.texi -o -name *.org ) -printf something

かっこがないので、かっこが必要です。

-name *.texi -o -name *.org -printf something

同じだろう

-name *.texi -o -name *.org -a -printf something

暗黙の内容があるからそして原子間の関係が与えられない限り、表現-oは次のとおりです。

patternmatch(...) || patternmatch(...) && printf(...)

そしてそして稼働率または操作はほとんどすべてのプログラミング言語で同じように機能し、乗算は加算よりも密接にリンクされています。そして、findランダムな表現をサポートしているので、自分が欲しいものが何であるかを知る方法はありません。(***)したがって、この場合は括弧がなければ望みどおりに動作しません。


-print他の人が指摘したように、find式に "action"(など)がない場合、デフォルトで一致-execするファイル名を印刷して暗黙的に式の周りに括弧を入れるので、あなたが持っているコマンドには括弧は必要ありません。

だから、

find "$fdir" -name "*.texi" -o -name "*.org"

のように振る舞う

find "$fdir" \( -name "*.texi" -o -name "*.org" \) -print

ただし、明示的に入力する場合は、-print正しい処理順序を得るために明示的に括弧を入力する必要があります。望むより:複数の '-name' と '-exec' を持つ 'find' は、最後に表示される '-name' のみを実行します。


戻るgrepgrep括弧なしで式を処理しないので、必要ありません。入れ子や演算子の概念はありません。そしてそしてまたは一般的に言えば。代わりに、ハードコードされた動作があります。--includeとの場合には、--exclude包含規則と除外規則の両方を満足させようとしているようです。 (または少なくとも1つの--includeルールはありますが、単一の--excludeルールではありません)。またはその他。どちらも静的ルールです。どのパターンが一致するかを示すより複雑な表現を提供することはできません。


(* GNU grepは中間項目をオプションとして処理し、オプションの処理はオプションではなく引数の前に停止するため、他の実装でもファイル名として扱うことができます。また、括弧を引用またはエスケープすることでこれを防ぐ必要があります。シェル;彼らがすることとは何の関係もありませんgrep。 )

grep(**繰り返しますが、オプションではない最初の引数がモードで、残りの引数のみがファイル名、または最後の引数が宛先であり、他の引数が移動するファイルのmv場合にのみ該当し、そのgit項目にのみ適用されます。他の操作を実行するツールなので、コマンドライン引数を異なる方法で使用する必要があります)。

(***誰かが評価式は次のように言ったことがあります。重要なこと findする。つまり、印刷するファイル名を探さずにファイルツリーを調べます。計算式それらの中で。外部コマンドを印刷して実行するのは単なる副作用です。 )

答え2

一般的なルールはありません。与えられたコマンドが引数として認識するのは、コマンドによって異なります。grep引数のグループ化に括弧を使用しないでください。

~のためfind、優先順位が次の場合にのみそして比較的または上書きする必要があります。これは数学で括弧を使用するのと似ています。あなたの例では、基本的な優先順位が式に同じ全体的な意味を与えるため、必要ありません。

find "$fdir" -name '*.texi' -o -name '*.org'

答え3

プログラムがコマンドライン引数をどのように解釈するかについての標準がないため、混乱が発生します。通常、パラメータの解釈はプログラマーの役割です。GNUコーディング標準提案されたプログラムの使用getopt()getopt_long()機能(〜GNU Cライブラリ)この目的のために。

これは、演算子の優先順位を定義する括弧の解釈が呼び出しシェルfindで使用される関数ではなく、関数の関数であることを意味しますfind。 「単純な」プログラマはgrepオプションの構文解析アルゴリズムをこのように実装しないため、grep最初は表記を理解できません。

しかし、参考にしてください括弧はシェルで特別な意味を持ちます。括弧は、埋め込みコンテンツが実行されるコマンドであることを示します。サブシェルから。したがって、公開したコマンドは実際には機能しないはずです。 @terdonが述べたように、最初に\( ... \)シェルがそれを渡すには、括弧(たとえば)をエスケープする必要があります。find

答え4

マニュアルには、find役に立つかっこの使い方についていくつかの洞察力があると思います。

2.12 原色と演算子の結合

演算子は、テストと操作に基づいて複雑な式を作成します。演算子は優先順位の降順でリストされます。

( expr )

強制優先順位。本当なら本当ですexpr

! expr
-not expr

偽であれば真ですexpr。一部のシェルでは、「!」を引用してシェル解析から保護する必要があります。

expr1 expr2 expr1 -a
expr2 expr1 -and expr2

偽の場合、expr2評価は実行されません。expr1

expr1 -o expr2 expr1 -or expr2

または本当ならexpr2評価しないでください。expr1

expr1 , expr2

両方ともリストされ、expr1常にexpr2評価されます。本当なら本当ですexpr2。値がexpr1削除されます。この演算子を使用すると、他のタスクの成功に頼ることなく、単一パスで複数の独立したタスクを実行できます。ファイルをタッチまたは削除するなどの副作用が発生する可能性があるか、expr2`を使用する可能性があるため、両方の操作は必ずしも完全にexpr1独立expr2 しているわけではありません。expr1-prune’ which would also affect

find各ファイル名にルートを持つディレクトリツリーは、結果がわかるまで(左の場合はfalse -and、の場合はtrue -or)式を左から右に評価して優先順位の規則に従って検索され、その時点でfindは次のファイル名に進みます。になります。

関連情報