将图案放在不同的列中

将图案放在不同的列中

我想打印每次在下一列中找到的模式,而不是像 grep 命令那样打印在下一行中。

例如file 1 当我这样做时,grep -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 variableName我们可以定义一个 awk 变量,我们定义了一个变量来传递我们想要捕获的 mached 行之后的行数。

/regex/旨在匹配所需的正则表达式针对 awk 的当前处理记录。

然后,我们使用 for 循环将每个匹配的行以及匹配后的第 1、2和3附加模式连接成单行,其中每个组都具有与记录号;接着就,随即getline语句我们正在读取匹配后的第一、第二和第三坐标线。

然后在最后,我们使用 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

相关内容