私は使用しfind
てgrep
コマンドします。
複数のオプションを連結するためにフラグと一緒に「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' のみを実行します。
戻るgrep
:grep
括弧なしで式を処理しないので、必要ありません。入れ子や演算子の概念はありません。そしてそしてまたは一般的に言えば。代わりに、ハードコードされた動作があります。--include
との場合には、--exclude
包含規則と除外規則の両方を満足させようとしているようです。 (または少なくとも1つの--include
ルールはありますが、単一の--exclude
ルールではありません)。またはその他。どちらも静的ルールです。どのパターンが一致するかを示すより複雑な表現を提供することはできません。
(* GNU grepは中間項目をオプションとして処理し、オプションの処理はオプションではなく引数の前に停止するため、他の実装でもファイル名として扱うことができます。また、括弧を引用またはエスケープすることでこれを防ぐ必要があります。シェル;彼らがすることとは何の関係もありませんgrep
。 )
grep
(**繰り返しますが、オプションではない最初の引数がモードで、残りの引数のみがファイル名、または最後の引数が宛先であり、他の引数が移動するファイルのmv
場合にのみ該当し、そのgit
項目にのみ適用されます。他の操作を実行するツールなので、コマンドライン引数を異なる方法で使用する必要があります)。
(***誰かが評価式は次のように言ったことがあります。重要なこと find
する。つまり、印刷するファイル名を探さずにファイルツリーを調べます。計算式それらの中で。外部コマンドを印刷して実行するのは単なる副作用です。 )
答え2
答え3
プログラムがコマンドライン引数をどのように解釈するかについての標準がないため、混乱が発生します。通常、パラメータの解釈はプログラマーの役割です。GNUコーディング標準提案されたプログラムの使用getopt()
とgetopt_long()
機能(〜GNU Cライブラリ)この目的のために。
これは、演算子の優先順位を定義する括弧の解釈が呼び出しシェルfind
で使用される関数ではなく、関数の関数であることを意味しますfind
。 「単純な」プログラマはgrep
オプションの構文解析アルゴリズムをこのように実装しないため、grep
最初は表記を理解できません。
しかし、参考にしてください括弧はシェルで特別な意味を持ちます。括弧は、埋め込みコンテンツが実行されるコマンドであることを示します。サブシェルから。したがって、公開したコマンドは実際には機能しないはずです。 @terdonが述べたように、最初に\( ... \)
シェルがそれを渡すには、括弧(たとえば)をエスケープする必要があります。find
答え4
マニュアルには、find
役に立つかっこの使い方についていくつかの洞察力があると思います。
演算子は、テストと操作に基づいて複雑な式を作成します。演算子は優先順位の降順でリストされます。
( 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は次のファイル名に進みます。になります。