ファイルから抽出および再配置

ファイルから抽出および再配置

一部のデータを抽出して並べ替えるファイルがあります。前のファイルには元のデータが含まれており、このファイルは入力です。

参照: 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を再起動にリセットします。次の参照を参照して再起動できます。

おすすめ記事