web-dev-qa-db-ja.com

awkを使用して単一のファイルから複数の正規表現に一致させる

シェルスクリプトを使用してHTMLファイルを解析しようとしています。

キャッチする必要がある4つの異なる正規表現があります:name=age=class=marks=

使用する

grep "name=\|age=\|class=\|marks=" student.txt

必要な行を取得することはできますが、これらの一致する行とともに、スコアを含む各一致の2行目も印刷する必要があります。

質問を参照してください: 一致する行と一致する行からn番目の行を印刷

私はコードを次のように変更しました:

awk '/name=\|age=\|class=\|marks=/{nr[NR]; nr[NR+2]}; NR in nr' student.txt

しかし、これはうまくいかないようです。同じawkコマンドで複数の正規表現を検索するにはどうすればよいですか?

6
debal

試してみてください:

awk '/foo/||/bar/' Input.txt
9
Rahul Patil

awk正規表現は拡張正規表現ですが、grep-Eがないものは基本正規表現です。拡張正規表現で:

awk '/name=|age=|class=|marks=/{nr[NR]; nr[NR+2]}; NR in nr'

標準の基本正規表現はnotに代替演算子があることに注意してください。

grep 'a\|b'

通常、すべてのgrepでは機能しません(ただし、GNU grepは拡張機能としてサポートします)。

grep -E 'a|b'
grep -e a -e b
grep 'a
b'

ただし、すべてのgrepで機能します。

4

Grepの使用

Afterコンテキストスイッチを使用してgrep(-A)を指定し、1一致後の最初の行を取得するには?

$ grep -E -A 1 "name=|age=|class=|marks=" student.txt

サンプルファイル。

$ cat student.txt 
name=
1st line after name
2nd line after name
age=
1st line after age
2nd line after age
class=
1st line after class
2nd line after class
marks=
1st line after marks
2nd line after marks

次に、上記のコマンドを実行すると:

$ grep -E -A 1 "name=|age=|class=|marks=" student.txt
name=
1st line after name
--
age=
1st line after age
--
class=
1st line after class
--
marks=
1st line after marks

Awkの使用

@RahulPatilがawkに構文を使用することを提案したように:

'/string1/||/string2/||...'

このような何かはあなたが探していることを行います。

$ awk '
  /name=/||/age=/||/class=/||/marks=/{nr[NR]; nr[NR+1]}; NR in nr
' student.txt 

$ awk '
  /name=/||/age=/||/class=/||/marks=/{nr[NR]; nr[NR+1]}; NR in nr
' student.txt
name=
1st line after name
age=
1st line after age
class=
1st line after class
marks=
1st line after marks
1
slm

Grepで「-A」フラグを使用してみましたか?一致した後に、後続のコンテキストの行を出力します。例えば: grep -A1 foo file.txtは、行をWord fooと一致させて印刷し、直後の行も印刷します。

1
Doug Carter