行の先頭のテキストを一致させ、最初のX行に一致する行を印刷するには?

行の先頭のテキストを一致させ、最初のX行に一致する行を印刷するには?

同様の質問が見つかりましたここしかし、それはまさに私が望むものではありません。

次のテキストファイルがあるとしましょう。

[...]

age: 10
country: United States
city: New York
name: John

age: 27
country: Canada
city: Toronto
name: Robert

age: 32
country: Mexico
city: Guadalajara
name: Pedro

[...]

「name:Robert」で始まる行を一致させ、一致した結果で最初の3行を印刷して、次の行のみを取得したいと思います。

age: 27
country: Canada
city: Toronto
name: Robert

ターミナルでどうすればいいですか?

答え1

使用grep

$ grep -B3 '^name: Robert$' input_file
age: 27
country: Canada
city: Toronto
name: Robert

答え2

あなたはすでに最良の方法を持っています。ただ使用することですgrep -B。ただし、「短絡モード」でPerlを使用することもできます。このモードは、スイッチによってアクティブになり、-00「行」は、2つの連続した改行、本質的に短絡として定義されることを意味します。これにより、次のことができます。

$ perl -00 -ne 'print if /name: Robert\b/' file
age: 27
country: Canada
city: Toronto
name: Robert

$

awkレコード区切り記号()を空白()に設定してRS同じ操作を実行することもできます''

$ awk -v RS='' '/name: Robert$/' file
age: 27
country: Canada
city: Toronto
name: Robert
$

awkのもう一つの利点は、Perlのように追加の改行を印刷しないことです。

答え3

データ型は、GNU recutils が使用する「recfile 形式」と同じです。これは、次のようにファイルを照会できることを意味します。

$ recsel -e 'name = "Pedro"' file
age: 32
country: Mexico
city: Guadalajara
name: Pedro

20歳以上のすべての人の名前を取得するには:

$ recsel -e 'age >= 20' -P name file
Robert

Pedro

など。

を参照してinfo recutilsください。GNU reutilsウェブサイトより多くの情報を知りたいです。

答え4

ラインエディタを使用してed最初にターゲットライン(g / /)を選択し、その周囲に範囲(-3、.)を作成し、その範囲(p)でコマンドを実行します。

ed -s inp <<\eof
g/^name: Robert$/-3,.p
eof

## Gnu sed in extended regex mode
## collect 4 lines in pattern space then print the whole pattern space on match else clip first line and append the next

sed -E ':1;$!{N;/(.*\n){3}/!b1;/\nname: Robert$/b};D' file

# using the -p option to autoprint current record 

perl -00 -pe '($_)=/((?:.*\n){3}name: Robert\n)/' file

出力:

age: 27
country: Canada
city: Toronto
name: Robert

関連情報