パターンを別の列に配置

パターンを別の列に配置

grepコマンドのように、次の行に印刷するのではなく、毎回次の列のパターンを印刷したいと思います。

たとえば、これを行うと、file 1grep -A3 "coordinate" file1>>file2の結果が表示されます。

coordinates
 X1 Y1 Z1
 X2 Y2 Z2
 X3 Y3 Z3
coordinates
 X1 Y1 Z1
 X2 Y2 Z2
 X3 Y3 Z3

しかし、私はこれを得たいと思います:

coordinates   coordinates
 X1 Y1 Z1       X1 Y1 Z1
 X2 Y2 Z2       X2 Y2 Z2
 X3 Y3 Z3       X3 Y3 Z3
   

ご協力ありがとうございました

答え1

awkを使用してください:

awk -v x=3 '/coordinates/ {
    for(recNr=0; recNr<=x; recNr++){
        data[recNr]=(data[recNr]==""?"": data[recNr] OFS) $0
        if(recNr<x) getline
    }
}
END { for(recNr=0; recNr<=x; recNr++) print data[recNr] }' infile

内部に-v variableNameawk変数を定義でき、キャプチャしたい加工ラインの後に行数を渡す変数を定義します。

これは/regex/必須事項と一致するように設計されています。正規表現awkの現在の処理履歴。

次に、 forループを使用して、一致する各行と一致する行1、2、3を追加パターンの単一行にリンクします。履歴番号;それからすぐgetline声明 我々は、一致の後、最初、2、3読んでいます。同等語ワイヤー。

最後に、forループを使用して、一緒にリンクされたすべてのレコードを順次繰り返して印刷します。


印刷物に審美的な幅を適用するには、以下を試してください。

awk -v x=3 -v width=15 '/coordinates/ {
    for(recNr=0; recNr<=x; recNr++){
        data[recNr]=(data[recNr]==""?"": data[recNr] OFS) sprintf("%*-s", width, $0)
        if(recNr<x) getline
    }
}
END { for(recNr=0; recNr<=x; recNr++) print data[recNr] }' infile

出力:

coordinates     coordinates
 X1 Y1 Z1        X1 Y1 Z1
 X2 Y2 Z2        X2 Y2 Z2
 X3 Y3 Z3        X3 Y3 Z3

coordinates注:次の3行に異なる行がある場合、これには含まれません。

答え2

awkを使用し、データが一度にメモリに入るほど大きくないとします。

$ cat tst.awk
BEGIN {
    OFS = "\t"
    numLines = 4
}
/coordinates/ {
    numBlocks++
    lineNr = 0
}
++lineNr <= numLines {
    blocks[numBlocks,lineNr] = $0
}
END {
    for ( lineNr=1; lineNr<=numLines; lineNr++ ) {
        for ( blockNr=1; blockNr<=numBlocks; blockNr++ ) {
            printf "%s%s", blocks[blockNr,lineNr], (blockNr<numBlocks ? OFS : ORS)
        }
    }
}

$ awk -f tst.awk file
coordinates coordinates
 X1 Y1 Z1    X1 Y1 Z1
 X2 Y2 Z2    X2 Y2 Z2
 X3 Y3 Z3    X3 Y3 Z3

関連情報