同様の質問が見つかりましたここしかし、それはまさに私が望むものではありません。
次のテキストファイルがあるとしましょう。
[...]
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