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 변수를 정의할 수 있으며, 캡처하려는 가공된 라인 뒤에 라인 수를 전달하는 변수를 정의합니다.
이는 /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