2

ファイルの名前を検索して、次の行を出力しようとしています。私はもともと次のように解決しました:

grep -A 1 "searchterm" filename

searchtermただし、これは行内のすべての場所を検索します。行の最初の部分でのみ一致が必要なため、これは問題です。

たとえば1234、次のファイルを探しているとします。

4567 otherstuff 1234
wrongsecondline
1234 otherstuff
rightsecondline

見つけよう4567 otherstuff 1234としているしwrongsecondline、本当に欲しかった1234 otherstuffrightsecondline

行の最初の項目のみを検索し、その行と 2 行目を印刷する方法について何か考えはありますか? ありがとう!

4

2 に答える 2

2

grep一致する行と次の行の両方を印刷するために使用します。

$ egrep -w -A1 "^1234" filename
1234 otherstuff
rightsecondline

awk上記と同じことを達成するために使用する†</sup>:

$ awk '$1=="1234"{print;getline;print}' filename
1234 otherstuff
rightsecondline

一致に続く行のみを印刷するために使用grepする(前の通知):<filename

$ grep -w -H --label=dummy -A1 '^1234' <filename | sed -ne 's#^dummy-##p'
rightsecondline

awk上記と同じことを達成するために使用する†</sup>:

$ awk '$1=="1234"{getline;print}' filename
rightsecondline

†連続する2行に検索語が含まれておらず、ファイルの最後の行に検索語が含まれていない場合


2つ以上の連続した行に検索語が含まれると予想される場合、たとえば

4567 otherstuff 1234
wrongsecondline
1234 otherstuff once
1234 otherstuff again
rightsecondline

...次に、awkステートフルに使用して、次と同じ出力を実現しますgrep -A1

$ awk 'pr_after{print;pr_after=0}$1=="1234"{print;pr_after=1}' filename
1234 otherstuff once
1234 otherstuff again
rightsecondline

...そしてawk、その行がそれ自体が一致している場合でも、一致に続く行を常に印刷するためにステートリーに使用します。

$ awk 'pr_after{print;pr_after=0}$1=="1234"{pr_after=1}' filename
1234 otherstuff again
rightsecondline

...または、awk1つ以上の一致する行の直後にある一致しない行のみを印刷するためにステートリーに使用して、grep -H | sed上記と同じ出力を実現します。

$ awk '$1=="1234"{pr_after=1;next}pr_after{print;pr_after=0}' filename
rightsecondline

上記の例で$1=="1234"{...}は、はパターン/アクションルールです。これは、最初の列がテキストと等しい場合は1234do ...pr_after{...}意味し、変数pr_afterがゼロ以外の空でない値に設定されている場合はdo ...を意味し、次の列を読み取ることgetlineを意味します。行を作成し、getlineの後のステートメントで実行を続行します。これは、次の行を読み取り、最初のパターンで評価を再開nextすることを意味します。

于 2012-12-01T03:56:25.703 に答える
1

選択基準を強化したくない場合、grep を使用することは完全に合理的ですが、参考までに、次のイディオムは awk を使用して、一致する特定のパターンを指定してレコードの範囲を選択する方法を説明しています。

a) Print all records from some pattern:

    awk '/pattern/{f=1}f' file

b) Print all records after some pattern:

    awk 'f;/pattern/{f=1}' file

c) Print the Nth record after some pattern:

    awk 'c&&!--c;/pattern/{c=N}' file

d) Print every record except the Nth record after some pattern:

    awk 'c&&!--c{next}/pattern/{c=N}1' file

e) Print the N records after some pattern:

    awk 'c&&c--;/pattern/{c=N}' file

f) Print every record except the N records after some pattern:

    awk 'c&&c--{next}/pattern/{c=N}1' file

g) Print the N records from some pattern:

    awk '/pattern/{c=N}c&&c--' file

変数名を "found" の "f" から "count" の "c" に変更したのは、変数が実際に何であるかをより表現できるようにするためです。

したがって、この場合、上記のイディオム「c」を次のように使用できます。

awk 'c&&!--c;/1234/{c=1}' file
于 2012-12-02T05:32:19.370 に答える