#始めに
いきなりですが、こんな感じでgrepをしたこと/見たことがある方は多いかと思います。
$ find . -name "*.php" | xargs grep hoge
これはカレントディレクトリ配下の「.php」がつくファイルから「hoge」という文字列を検索するコマンドになります。
以前、「なぜxargsが必要なのか」「|だけじゃダメなのか」と問われたことがあります。
頭の中ではなんとなく理解しているのですが、うまく他人に説明することができませんでした。
なので今回は備忘録を兼ねて、xargsと|(パイプ)の役割について記述していきたいと思います。
#両者の役割
##xargs
コマンドの標準出力結果を次のコマンドの引数として受け取る。
##|(パイプ)
コマンドの標準出力結果を受け取り次のコマンドに渡す。
うん。つまり?
文面じやわかりにくいですね。
この後、実際にgrepを使ってどのように動くか見ていきたいと思います。
#grepを例にして違いを見てみる
##準備
テスト用のディレクトリ内でhoge.phpとfoo.phpを用意する。
中身は2つとも同じ。
$ find . -name "*.php"
./hoge.php
./foo.php
$ cat *
<?php
echo 'hoge';
<?php
echo 'hoge';
findの標準出力結果は、上記の通りですがこの結果を次のコマンドに渡します。
##grepで結果を比較
- |(パイプ)のみの場合
$ find . -name "*.php" | grep hoge
./hoge.php
findの標準出力結果そのものの中からgrepしていることがわかる。
- xargsをつけた場合
$ find . -name "*.php" | xargs grep hoge
./hoge.php:echo 'hoge';
./foo.php: echo 'hoge';
findの標準出力結果をgrepの引数にして実行していることがわかる。
つまり簡単に言うと
grepの対象が
前者は
「./hoge.php ./foo.php
という文字列の中から検索」
後者は
「./hoge.phpと./foo.php
というファイルの中から検索」
と考えると分かりやすいと思います。