我想打印每次在下一列中找到的模式,而不是像 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
在里面awk,-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