私のファイルはfile.txt
次のとおりです。
[NamesA]
Andreas
Alex
[NamesB]
Bernd
Bruno
[NamesC]
Casper
[NamesD]
Doris
grep
次の3つの異なる出力を達成するために、これをbashスクリプトで使用または使用したいと思います。awk
出力
[NamesB] Bernd Bruno
出力
[NamesB] Bernd Bruno [NamesC] Casper
出力
[NamesD] Doris
私は試した:
grep -oP '\[NamesB\].*?' file.txt
ただし、[NamesB]
代わりに次のテキストブロックのみを取得します。私はテキストをすぐ後ろにインポートしましたが、新しい行にはインポートできませんでした。
それはすべてです。で始まる次の行を少なくともすべて得ることができれば[NamesB]
それはうまくいきません。
- したがって、1.の出力は、
[NamesB]
次の項目で始まり終わるすべての項目を印刷することで最も簡単になると想像できます[
。 - 2番は出力1番と似ていますが、2回実行されることを想像する
grep
こともできます。一度[NamesB]
、その後[NamesC]
[
しかし、以下がないので、3.ではこれはどのように機能しますか?そして、で始まる未知の次のブロックがあるかもしれません[
。
その後、コマンドはまたは[NamesB]
で始まるテキストの印刷を開始し、次に開く角かっこまたは[
ファイルの終わりで停止する必要があります。
PS:同様の質問を投稿して解決策を見つけましたが、全文行。この質問では、別の状況、つまり1行ではなくテキストブロックがあります。
ベストアンサー1
印刷するレコードを選択するための要件は明確ではありませんが、おそらくこれがawkでやりたいことです。
出力1、オプション1(一度に1行ずつ読みます):
$ awk '/^\[/{f=(/^\[NamesB]/)} f' file.txt
[NamesB]
Bernd
Bruno
出力1、オプション2(一度に1つの複数行レコードを読む)
$ awk -v RS= -v ORS='\n\n' -F'\n' '$1 == "[NamesB]"' file.txt
[NamesB]
Bernd
Bruno
出力2、オプション1(NamesBレコードとそれに続くレコードを印刷):
$ awk -v RS= -v ORS='\n\n' -F'\n' '$1 == "[NamesB]"{c=2} c&&c--' file.txt
[NamesB]
Bernd
Bruno
[NamesC]
Casper
出力2、オプション2(入力位置に関係なくNamesBおよびNamesCレコードを印刷):
$ awk -v RS= -v ORS='\n\n' -F'\n' '$1 ~ /^\[Names[BC]]$/' file.txt
[NamesB]
Bernd
Bruno
[NamesC]
Casper
出力3、オプション1(NamesDレコード印刷):
$ awk -v RS= -v ORS='\n\n' -F'\n' '$1 == "[NamesD]"' file.txt
[NamesD]
Doris
出力3、オプション2(名前が何であれ、入力の4番目のレコードを印刷します):
$ awk -v RS= -v ORS='\n\n' -F'\n' 'NR == 4' file.txt
[NamesD]
Doris
また、以下に関連して:
少なくとも[NamesB]で始まる次の行をすべて取得できる場合
以下はトリックを行います。
$ awk -v RS= -v ORS='\n\n' -F'\n' '$1 == "[NamesB]"{f=1} f' file.txt
[NamesB]
Bernd
Bruno
[NamesC]
Casper
[NamesD]
Doris
もちろん、さまざまな基準に基づいて出力を生成するために他の多くのスクリプトを書くことができます。正しいスクリプトは、出力するチャンクを選択するときの要件によって異なります。