나는 이 질문을 보고 비슷한 것을 하고 싶었습니다.열의 값이 변경되면 행 인쇄
기본적으로 다음과 같은 (탭으로 구분된) 파일이 있습니다.
A 0 10 loss
A 10 20 loss
A 20 30 loss
A 30 40 no
A 40 50 no
A 50 60 no
A 60 70 no
A 70 80 gain
...
열 4가 "loss" -> "no" 또는 "no" -> "gain"에서 변경되는 두 줄을 인쇄하고 싶으므로 출력은 다음과 같습니다.
A 20 30 loss
A 30 40 no
A 60 70 no
A 70 80 gain
4열의 값은 무엇이든 가능하지만 변경 사항을 포함하는 두 줄을 인쇄하고 싶습니다.
이것은 awk로 할 수 있는 것처럼 보이지만 그다지 익숙하지는 않습니다.
답변1
이를 통해 awk
다음을 수행할 수 있습니다.
awk 'BEGIN { getline; cmp=$4; preline=$0 }
cmp!=$4{ print preline, $0 } { cmp=$4; preline=$0 }' OFS='\n' infile
A 20 30 loss
A 30 40 no
A 60 70 no
A 70 80 gain
BEGIN
블록 에서 첫 번째 행을 읽고 명명된 cmp
변수 에 열 #4를 저장하고 preline
나중에 이전 행의 열 #4를 현재 행의 열과 비교하고 변경 값이 있고 preline
읽은 값이 인쇄됩니다. 현재 행 기준 $0
; 다음 블록은 단순히 현재 행의 4번째 열을 업데이트하고 다음 실행 시 전체 행을 이전 행으로 다시 업데이트합니다.
답변2
sed
기호 편집기를 사용하면 GNU
다음을 수행할 수 있습니다.
sed -Ee '
$d;N
/\s(\S+)\n.*\s\1$/!p
D
' input.file
우리는 항상 패턴 공간에 두 개의 라인을 가지고 N
마지막 필드의 전환을 찾습니다. 하나를 감지하면 /\s(\S+)\n.*\s\1$/!p
전체 패턴 공간을 인쇄합니다. 그런 다음 D
첫 번째 부분의 사용이 이 단계에서 끝나기 때문에 변환 여부에 관계없이 패턴 공간의 첫 번째 부분을 제거합니다.
제어는 sed 코드의 맨 위로 이동하며, 아직 eof에 도달하지 못한 경우 프로세스를 다시 반복합니다. Eof는 작업을 중지합니다 $d
.
산출:
A 20 30 loss
A 30 40 no
A 60 70 no
A 70 80 gain
답변3
왜 안 돼:
$ awk '(NR > 1) && (LAST !~ $4 "$") {print LAST; print $0} {LAST = $0}' file
A 20 30 loss
A 30 40 no
A 60 70 no
A 70 80 gain