一部のデータを抽出して並べ替えるファイルがあります。前のファイルには元のデータが含まれており、このファイルは入力です。
参照: cve, 2017-8962 西ドイツ:45885 参照: cve, 2016-10033 参照: cve, 2016-10034 参照: cve, 2016-10045 参照: cve, 2016-10074 西ドイツ:45917 リファレンス: cve, 2017-8046 西ドイツ:45976 リファレンス: cve, 2018-6577 リファレンス: cve, 2018-6578 西ドイツ:46062
次のファイルは、必須出力を含む新しいファイルです。
参照: cve, 2017-8962 西ドイツ:45885 参照: cve, 2016-10033 西ドイツ:45917 参照: cve, 2016-10034 西ドイツ:45917 参照: cve, 2016-10045 西ドイツ:45917 参照: cve, 2016-10074 西ドイツ:45917 リファレンス: cve, 2017-8046 西ドイツ:45976 リファレンス: cve, 2018-6577 西ドイツ:46062 リファレンス: cve, 2018-6578 西ドイツ:46062。
注:たとえば、sid:45917には4つの参照があります(参照:cve、2016-10033参照:cve、2016-10034参照:cve、2016-10045参照:cve、2016-10074)。 sidは他のsidに追加されます(注:sidの後には常に参照が続きます。)、このように重複したブロックがあるため、複数の参照がある場合は、新しいファイルの順序で追加する必要があります。
ベストアンサー1
使用しているようです。後で sid:
s(複数references:
の後にシングルsids:
=>ペアreferences:
合計sid:
)、2つのソリューション。
解決策1:反転
単にtac
コマンドを使用してください(それは猫入力と出力の逆順(逆順):tac input | awk | tac > output
awk部分の場合、sをコピーするだけですsid:
。
gawk '/^sid:/{sid=$0};/^reference:/{print sid "\n" $0}'
解決策2:配列
到着するとすぐに配列に保存し、そのreference:
項目に出会うと吐き出します。sid:
gawk 'BEGIN{r=0};/^reference:/{ref[r++]=$0};/^sid:/{for(n=0;n<r;n++){print ref[n] "\n" $0};r=0}' /tmp/test.txt
/^reference:/{ref[r++]=$0}
:ref ...で始まる各行に対して、行を配列に格納し、 "r"ポインタを次の要素に移動します。
/^sid:/{for(n=0;n<r;n++){print ref[n] "\n" $0};r=0}
:行がsidで始まるたびにrポインタ(for ...)まで配列全体を繰り返し、要素ごとに保存されている参照と現在の行(= sid)を印刷し、rを再起動にリセットします。次の参照を参照して再起動できます。