テキストの検索後に特定の行を読み取る方法は?


12

テキストを見つけた後、特定の行数を読み取るにはどうすればよいですか?

例えば。:

「Unix」が見つかったら、次の2行を読みます。

Test 1
Test 2
Test 3
Test 4
UNIX
Test 5
Test 6
Test 7
Test 8
Test 9

結果は次のようになります。

Test 5
Test 6

注:最後の例の「Unix」は引数なので、他のテキストでもかまいません。

私が持っているもの:

私はまだアイデアが足りないので、ただ光が必要です。それを行う別のスクリプトを作成することを考えてください。

回答:


10

awk解決策:

$ awk '$0 == "UNIX" {i=1;next};i && i++ <= 2' file
Test 5
Test 6

説明

  • /^UNIX$/{i=1;next}:が見つかればUNIX、変数を設定しi = 1、次の入力に処理します。

  • 変数iが設定されている場合(つまり、が表示された場合UNIX)、i && i++ <= 2次の2行でのみ真の値に評価されUNIXawkデフォルトのアクションが実行されますprint $0

  • 見る前にUNIXi定義されていなかったと後に3行目から始まりUNIXi表現が作る2よりも値が大きいほど、持っていたi && i++ <= 2発生しない、falseに評価さawkのDOは何も。


テストした後、このエラーメッセージが表示された解決策は次のとおりです。1行目付近のエラーsystaxが1行目付近で救済
コールド

@コールド:何を実行しましたか?$回答の最初の記号はシェルプロンプトであり、awkコマンドの一部ではないことに注意してください。
cuonglm 2014年

別のバリアント:awk '/^UNIX$/ {s=NR;next} s && NR<=s+2'
musiphil 2014年

@cuonglm
寒さ

@コールド:あなたのOSは何ですか?
cuonglm 2014年

12

grep解決策:

grep -A2 -P '^UNIX$' file

説明: -A意味:一致の後に次の2行を出力します

または awk:

awk '$0=="UNIX"{getline; print; getline; print}' file

説明:このステートメントは、行($0=="UNIX")でUNIXを検索します。それが指定されている場合は、次の次をバッファに入れ(getline)、バッファを出力します(print)。これは2回行われます。

または使用sed

sed -n '/^UNIX$/{n;p;n;p}' file

説明: UNIX(/^UNIX$/)に移行します。これが見つかると、の一部がtxecuteされます{...}n次をp意味し、印刷を意味します。これも2回行われます。


@chaosに感謝します、私はあなたが与える最後の2つのオプションを試します。PLease各オプションの説明を追加してください。理解して実行します。
寒さ

行数が変わる場合、最後の2つのオプションでいくつの変更を行いますか?ありがとう
冷たい

@コールド私の編集を参照してください。行getline; print;awkステートメントのn;p;一部またはステートメントの一部を繰り返す場合に番号を変更するにはsed
2014年

@chaosに感謝しますが、行数が多いほど表現が増え、変更は私の意見では実現不可能です。そう思いませんか?100行なら?
2014年

@Cold次に、grepソリューションをで使用しgrep -A100 -P '^UNIX$' file | tail -n +2ます。尾の部分は最初の先取特権を削除することです。他のもの(sed、awk)では、ループを作成する必要があるため、ループが単純になります。
2014年

4
grep -A 2 UNIX file.txt

このため、grepのマンページにオプションが説明されています。

  -A NUM, --after-context=NUM
      Print NUM  lines  of  trailing  context  after  matching  lines.
      Places  a  line  containing  --  between  contiguous  groups  of
      matches.

こんにちは@Twinkles、良い答えですが、私のgrepにはこのオプション "hblcnsviw"しかありません。しかし、論理は良いです。感謝
コールド

これUNIXも出力に出力されます。
cuonglm 2014年

を省略するにはUNIX、パイプでtail[...] | tail -n +1、またはにパイプしsedます[...] | sed '1d'
DopeGhoti 2014年

1
@DopeGhoti:tailとのsed '1d'候補UNIXは、入力テキストに1回だけ表示される場合にのみ正しく機能します。他のすべての回答では、複数の発生が可能です。提案する方が良いかもしれません... | grep -v UNIX。場合は確かに、これは厄介を取得しUNIXライン15および17に表示されます
G-マンが「回復モニカ言う

良い点。私はそれがsed何らかの形でsed '/UNIX/d;n;n;p/' /path/to/fileで実行できると確信しています。
DopeGhoti 2014年

0

これはうまくトリックをするようです:

sed -n '/UNIX/{n;p;n;p}' /path/to/file

コンセプトの証明:

$ for i in {1..9}; do echo $i; done | sed -n '/4/{n;p;n;p}'
5
6

1
forループの周りのサブシェルは必要ありません。
追って通知があるまで一時停止しました。

確かにそうではありません。それは私がその日の早い段階でその砲弾の真ん中にいた他のいくつかの奇妙なものの残骸でした。括弧を削除しました。
DopeGhoti 2014年

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.