Grepのは、このためには適していませんが、あなたは別のライン間の関係について尋ねます。 Grepはに何度か強制することができます複数の行にまたがるもの(ab)は、ヌルバイトで区切られた行を必要とする-z
フラグを使用しますが、通常はそれほど美味しくありません。
Awkのは、簡単な解決策を可能にする:これは、RS
TAGDESCRIPTIONS
にレコードセパレータを設定
$ awk 'BEGIN{RS="TAGDESCRIPTIONS"}/foo/{print $1}' infile
bar
ので、入力は、3つのレコード(改行\n
意味する)として解釈される:
<empty record>
example\nTAGS tmp\nTAGS line\n
bar\nTAGS com\nTAGS foo\n
ファイルがレコードセパレータで始まるため、最初のファイルは空です。
各レコードについて、最初の改行まではタグの説明です。私たちは
/foo/{print $1}
と言うことはこれです:レコードは、レコード(説明)の最初のフィールドを印刷、foo
に一致する場合。
これはまったく爆弾ではありません。記述が複数の単語で構成されている場合は、最初のものだけが出力されます。タグの代わりに説明が一致すると、それは偽陽性です。レコードにfoobar
が含まれていて、bar
ではなく、それでも一致します。
この入力例では、シンプルなソリューションを投げるでしょう:
TAGDESCRIPTIONS foo
TAGS blah
TAGDESCRIPTIONS example
TAGS tmp
TAGS line
TAGS foobar
TAGS barfoo
TAGDESCRIPTIONS bar and more words
TAGS com
TAGS foo
は含むfoo
、タグfoo
とタグの説明や複数の単語でのタグの記述があります。
我々は、検索文字列に説明以外の各要素を比較し、改行でレコードを分割してすべてを修正することができ:
bar and more words
もたらす
awk '
BEGIN { RS = "TAGDESCRIPTIONS *" }
{
# Split record at newlines, store in arr
split($0, arr, "\n")
# Skip first element (description), compare to 'foo'
for (i = 2; i <= length(arr); ++i) {
if (arr[i] ~ " +foo$") {
# Matches - print description
print arr[1]
# No need to look at the rest of the record
break
}
}
}' infile
正確には、マルチ文字レコードセパレータとlength
関数のため、GNU awkです。
マルチキルRSと 'length(array)'のためにgawk固有のことを言及する必要があります。 –