여전히 복잡한 로그 파일로 인해 어려움을 겪고 있습니다. 내가 원하는 것은 먼저 문자열 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
(있는 경우)이 인쇄됩니다(또는 둘 다 인쇄되지 않습니다).
변수 p
및 p2
는 수정되지 않은 이전 행과 두 번째 열을 각각 보유합니다.