@Ed Morton:私はあなたに同意しません。 sed
を見つけました 非常に便利でシンプル (パターンとホールド バッファーの概念を理解すれば)、複数行の grep を行うエレガントな方法を考え出すことができます。
たとえば、ホスト名と各ホストに関するいくつかの情報を含むテキスト ファイルを取り上げてみましょう。その間には、私は気にしませんがたくさんのジャンクがあります。
Host: foo1
some junk, doesnt matter
some junk, doesnt matter
Info: about foo1 that I really care about!!
some junk, doesnt matter
some junk, doesnt matter
Info: a second line about foo1 that I really care about!!
some junk, doesnt matter
some junk, doesnt matter
Host: foo2
some junk, doesnt matter
Info: about foo2 that I really care about!!
some junk, doesnt matter
some junk, doesnt matter
私にとって、ホスト名と対応する info
の行を取得する awk スクリプト この行は、sed でできることよりも少し時間がかかります:
sed -n '/Host:/{h}; /Info/{x;p;x;p;}' myfile.txt
出力は次のようになります:
Host: foo1
Info: about foo1 that I really care about!!
Host: foo1
Info: a second line about foo1 that I really care about!!
Host: foo2
Info: about foo2 that I really care about!!
( Host: foo1
に注意してください 出力に 2 回表示されます。)
説明:
<オール>-n
明示的に印刷しない限り、出力を無効にしますHost:
を見つけて配置します ホールド バッファへの行 (h)Host:
を出力します。 行を再交換 (x) し、Info:行を出力 (p) します。はい、これは単純な例ですが、単純な sed ワンライナーですぐに対処できる一般的な問題だと思います。与えられた予測可能なシーケンスに依存できないタスクなど、はるかに複雑なタスクには、awk が適している場合があります。
sed がファイルを 1 行ずつ読み取ると、現在読み取られている行が pattern に挿入されます。 バッファ (パターン スペース)。パターン バッファは一時バッファのようなもので、現在の情報が保存されるスクラッチパッドです。 sed に印刷するように指示すると、パターン バッファーが印刷されます。
ホールド バッファ / ホールド スペースは長期ストレージのようなもので、何かをキャッチして保存し、後で sed が別の行を処理しているときに再利用できます。ホールド スペースを直接処理するのではなく、それを使用して何かをしたい場合は、それをコピーするか、パターン スペースに追加する必要があります。たとえば、印刷コマンド p
パターンスペースのみを印刷します。同様に、s
パターン空間で動作します。
以下に例を示します:
sed -n '1!G;h;$p'
(-n オプションは行の自動出力を抑制します)
ここには 3 つのコマンドがあります:1!G
、 h
と $p
. 1!G
アドレス 1
を持っています (最初の行)、しかし !
ただしどこでもコマンドが実行されることを意味します 最初の行に。 $p
一方、最後の行でのみ実行されます。すると、次のようになります:
h
最初の行を hold にコピーします スペース。G
を実行します。 ホールド バッファの内容をパターン バッファに追加し、改行で区切ります。パターン スペースには、2 行目、改行、1 行目が含まれるようになりました。h
コマンドは、パターン バッファの連結された内容をホールド スペースに挿入します。ホールド スペースには、反転した行 2 と 1 が保持されます。
最後に、最後の行が読み取られ、ホールド スペース (前のすべての行を逆の順序で含む) がパターン スペースに追加された後、パターン スペースは p
で出力されます。 .ご想像のとおり、上記は tac
とまったく同じことを行います コマンドは -- ファイルを逆に印刷します。
@Januaryの回答と例は素晴らしいですが、説明は私にとって十分ではありませんでした。 sed -n '1!G;h;$p'
がどのように正確に理解されるまで、多くのことを検索して学ばなければなりませんでした。 動作します。そこで、私のような人のためにコマンドについて詳しく説明したいと思います.
まず、コマンドが何をするか見てみましょう。
$ echo {a..d} | tr ' ' '\n' # Prints from 'a' to 'd' in each line
a
b
c
d
$ echo {a..d} | tr ' ' '\n' | sed -n '1!G;h;$p'
d
c
b
a
tac
のように入力を反転します コマンドが行います。
sed
は行ごとに読み取るので、パターン スペースで何が起こるか見てみましょう 保留スペース 各行で。 h
として コマンドは、パターン スペースの内容をホールド スペースにコピーします。両方のスペースのテキストは同じです。
Read line Pattern Space / Hold Space Command executed
-----------------------------------------------------------
a a$ h
b b\na$ 1!G;h
c c\nb\na$ 1!G;h
d d\nc\nb\na$ 1!G;h;$p
最終行 $p
d\nc\nb\na$
を出力します にフォーマットされています
d
c
b
a
各行のパターン スペースを見たい場合は、 l
を追加できます コマンド。
$ echo {a..d} | tr ' ' '\n' | sed -n '1!G;h;l;$p'
a$
b\na$
c\nb\na$
d\nc\nb\na$
d
c
b
a
各スペースがどのように使用されるかを段階的に示しているので、このビデオチュートリアルの理解はsedの仕組みを理解するのに非常に役立ちました。 hold spaced は 4 番目のチュートリアルで参照されていますが、sed
に慣れていない場合は、すべてのビデオを視聴することをお勧めします。 .
また、GNU sed ドキュメントと Bruce Barnett の Sed チュートリアルも非常に参考になります。