조건부로 교대로 인쇄

조건부로 교대로 인쇄

여전히 복잡한 로그 파일로 인해 어려움을 겪고 있습니다. 내가 원하는 것은 먼저 문자열 X와 일치하는 행을 찾은 다음 문자열 Y와 일치하는 행을 찾는 것입니다. 그러면 함께 인쇄하고 싶습니다. 문제는 때때로 X는 있지만 Y는 없다는 것입니다.

입력 예

31 X
32 Y
33 X
34 Y
35 X
36 X
37 Y
38 X
39 X

예상 출력

31 X
32 Y
33 X
34 Y
36 X
37 Y

따라서 35, 38, 39행은 문자열 Y가 없기 때문에 생략됩니다.

내 출발점은 다음과 같습니다.

cat $filename | grep -E X\|Y | grep -A1 'X'

그러나 이는 행 35, 38, 39를 필터링하지 않습니다. 내가 원하는 것은 조건입니다. Y가 있으면 X 행만 인쇄한 다음 Y 행을 인쇄합니다. 그렇지 않으면 아무것도 인쇄되지 않습니다.

답변1

사용 sed:

sed -n ':b /X/ { h; n; /Y/! b b; H; x; p; }'

산출:

31 X
32 Y
33 X
34 Y
36 X
37 Y

답변2

다른 sed:

$ sed -e '/X/{
    $!N
    /\n.*Y/!D
}' file
31 X
32 Y
33 X
34 Y
36 X
37 Y

답변3

이를 수행하는 데는 여러 가지 도구가 있습니다. 가지고 있는 경우 pcregrep(배포 저장소에 있어야 함) 다음과 같이 할 수 있습니다.

$ pcregrep -M 'X\n[^\n]+Y' file 
31 X
32 Y
33 X
34 Y
36 X
37 Y

-M스위치를 사용하면 패턴이 개행 문자, 정규식 일치 X, 그 뒤에 개행 문자, 개행이 아닌 문자 및 와 일치할 수 있습니다 Y.


또 다른 옵션은 이전 줄이 일치하면 저장하고, 일치하면 X현재 줄과 함께 인쇄하는 작은 스크립트를 작성하는 것입니다 Y. 예를 들면 다음과 같습니다 awk.

$ awk '{if(last~/X/ && /Y/){print last"\n"$0}last=$0}' file 
31 X
32 Y
33 X
34 Y
36 X
37 Y

또는 펄:

$ perl -ne '$last=~/X/ && /Y/ && print "$last$_"; $last=$_' file 
31 X
32 Y
33 X
34 Y
36 X
37 Y

답변4

질문에 태그가 지정되었으므로 awk:

$ awk 'p2 == "X" && $2 == "Y" { print p; print } { p = $0; p2 = $2 }' file
31 X
32 Y
33 X
34 Y
36 X
37 Y

그러면 한 줄 X과 그 바로 다음 줄 Y(있는 경우)이 인쇄됩니다(또는 둘 다 인쇄되지 않습니다).

변수 pp2는 수정되지 않은 이전 행과 두 번째 열을 각각 보유합니다.

관련 정보