4

パイプを使用して、他のコマンドの引数として標準出力を渡す方法についての洞察を探しています。

たとえば、次の場合を考えてみます。

ls | grep Hello

grepの構造は次のパターンに従いますgrep SearchTerm PathOfFileToBeSearched。私が説明した場合、Helloという単語がと見SearchTermなされ、lsの結果が検索対象のファイルとして使用されます。しかし、それを切り替えたい場合はどうなりますか?lsの標準出力をSearchTermにし、grepに続く引数を使用したい場合はどうなりPathOfFileToBeSearchedますか?一般的な意味で、パイプが前のコマンドの標準出力で満たされる引数を制御したいと思います。これは可能ですか、それともコマンドのスクリプト(たとえばgrep)がどのように書かれたかに依存しますか?

手伝ってくれてどうもありがとう!

4

2 に答える 2

9

grepそれ自体は、ファイル名を指定しなかった場合にstdinを開くように構築されます(したがって、の出力を取得しますls)。ここには本当の一般的なメカニズムはありません-単なる慣習です。

の出力をls検索語にしたい場合は、シェルを介してこれを行うことができます。したがって、サブシェルと置換を利用します。

$ grep $(ls) filename.txt

このシナリオlsでは、サブシェルで実行され、そのstdoutがキャプチャされ、の引数としてコマンドラインに挿入されgrepます。ls出力にスペースが含まれている場合、これにより。の混乱が生じることに注意してくださいgrep

于 2013-01-17T16:24:45.880 に答える
7

これには基本的に2つのオプションがあります。シェルコマンド置換とxargs。ブライアン・アグニューは前者について書いたばかりです。xargsstdinを取得し、実行するコマンドの引数に変換するユーティリティです。だからあなたは走ることができます

ls | xargs -n1 -J % grep -- % PathOfFileToBeSearched

そして、によって出力されたファイルごとに、指定した他のファイル内で出力されたファイル名のgrepに対してls実行されます。これは異常な呼び出しです。通常、コマンドの最後に1つ以上の引数を追加するために使用されますが、ここでは特定の場所に1つの引数を追加する必要があるため、引数を使用してそれを調整しました。より一般的な使用法は次のようなものですgrep -e filename PathOfFileToBeSearchedlsxargs-n-J

ls | xargs grep -- term

lsによって出力されたすべてのファイルを検索しますterm。もちろん、現在のディレクトリにファイルが必要な場合は、パイプラインなしでこれをより簡単に行うことができます。

grep -- term *

同様に、逆の配置では、

for filename in *; do
  grep -- "$@" PathOfFileToBeSearched
done

重要なxargs注意点が1つあります。によって生成されたファイル名の空白文字はls適切に処理されません。そのためには、GNUユーティリティがあれば、find代わりに使用できます。

find . -mindepth 1 -maxdepth 1 -print0 | xargs -0 -n1 -J % grep -- % PathOfFileToBeSearched

空白の代わりにNUL文字を使用してファイル名を区切る

于 2013-01-17T16:40:11.347 に答える