2개 패턴 사이의 선 추출(2개 패턴 포함)

2개 패턴 사이의 선 추출(2개 패턴 포함)

다음과 같은 데이터 구조를 가진 파일이 있습니다

1, p1, p2, p3, p4, p5, p6, p7
2, p9, p10,,
2, q1, q2, q3, q4, q5, q6, q7
2, q9, q10,,
2, r1, r2, r3, r4, r5, r6, r7
2, r9, r10,,
1, s1, s2, s3, s4, s5, s6, s7
2, s9, s10,,
...

나는 1로 시작하고 로 끝나는 모든 줄을 얻고 싶습니다.

1, p1, p2, p3, p4, p5, p6, p7
2, p9, p10,,
1, s1, s2, s3, s4, s5, s6, s7
2, s9, s10,,

가능하다면,

1, p1, p2, p3, p4, p5, p6, p7, 2, p9, p10,,
1, s1, s2, s3, s4, s5, s6, s7, 2, s9, s10,,

sed나 awk를 사용하여 이 작업을 어떻게 수행할 수 있나요?

답변1

sed다음은 마지막으로 발생한 줄 뒤에 일련의 줄을 연결하는 솔루션입니다 .,,$^1

sed -e '/^1/{x;s/\n/ /gp;d' -e '};/,,$/H;$G;D
' <<\IN                                                                          
1, p1, p2, p3, p4, p5, p6, p7
2, p9, p10,,
2, q1, q2, q3, q4, q5, q6, q7
2, q9, q10,,
2, r1, r2, r3, r4, r5, r6, r7
2, r9, r10,,
1, s1, s2, s3, s4, s5, s6, s7
2, s9, s10,,
IN

a로 시작하는 줄의 기존 공간과 패턴 공간을 변경 x하고 교체가 성공한 경우 기존 공간 이전의 내용만 인쇄합니다 . 로 끝나는 줄에는 ewline 문자 뒤에 이전 공백이 추가 되고 ewline 문자가 처음 나타날 때까지 모든 줄이 제거됩니다 . 마지막 줄 에서 이전 공백은 ewline 뒤의 패턴 공간에 추가됩니다. 따라서 제거되면 이전 공백에 포함된 내용만 포함하는 스크립트 상단에서 줄 루프를 다시 시작하여 필요에 따라 인쇄합니다.h^1s///ph,,$H\nD\n$H\nDH

산출:

1, p1, p2, p3, p4, p5, p6, p7 2, p9, p10,, 2, q9, q10,, 2, r9, r10,,
1, s1, s2, s3, s4, s5, s6, s7 2, s9, s10,,

반면, 이후에 이런 일이 발생하지 않도록 하려면 /,,$/다음을 수행할 수 있습니다.

sed -e '/^1/{x;y/\n/ /;s/,,.*/,,/p;d' -e '};/,,$/H;$G;D'

동일한 입력이 인쇄되면 다음과 같습니다.

1, p1, p2, p3, p4, p5, p6, p7 2, p9, p10,,
1, s1, s2, s3, s4, s5, s6, s7 2, s9, s10,,

그러나 일치 항목이 /,,$/바로 뒤따르지 않더라도 /^1/줄은 인쇄됩니다 . 입력에서 즉시 연속되는 쌍만 필요한 경우 다음을 수행할 수도 있습니다.

sed -n '/^1/!d;$p;N;/\n1/P;/,,$/s/\n/ /p;D'

작동 방식은 다음과 같습니다.

  • 먼저 d출력에서 !​​시작하지 않는 모든 것을 제거합니다./^1/
    • 여기 N에는 소개하지만 끝나지 않는 줄 이 포함됩니다 /,,$/.
  • 이것이 마지막 입력 라인인 경우 다음 명령이 스크립트를 종료하므로 $패턴 공간이 여기에 인쇄됩니다 .p
  • /^1/일치할 때 N패턴 공간의 \newline 문자 에 ext 입력 행을 추가합니다.
  • 추가 행인 경우반품a로 시작하면 이전 항목을 인쇄합니다 /\n1/.P
    • P\n패턴 공간에서 처음으로 나타나는 ewline 만 인쇄됩니다.
  • 추가 입력 라인을 가져온 후 N패턴 공간이 $match 로 끝나는 경우 삽입된 ewline 문자를 공백 문자로 /,,$/바꾸고 결과를 인쇄합니다.s///\np
  • 패턴공간은언제나 D처음 나타나는 ewline 문자까지 제거합니다 \n.
    • ...따라서 N외부 입력 줄이 일치하지 않으면 /,,$/스크립트의 첫 번째 줄로 다시 전송됩니다. 이때 일치하는 내용이 없으면 완전히 삭제 ^1됩니다 d.
    • ... /,,$/이 시점에서 ewline이 완전히 제거되었기 때문에 여기 프로세스에서도 완전히 제거되었습니다.\n

이것이 의미하는 바는 /^1/선이 서로 연결되어 있으면 계속 인쇄되고, 선이 ,,$a로 끝나지 않으면 ^1인쇄되지 않는다는 것입니다.

답변2

첫 번째 쿼리와 관련하여 -esed에서 표현식 결합을 사용할 수 있습니다.

~$ sed -n -e '/^1/p' -e '/,,$/p' f
1, p1, p2, p3, p4, p5, p6, p7
2, p9, p10,,
2, p9, p10,,
2, p9, p10,,
1, p1, p2, p3, p4, p5, p6, p7
2, p9, p10,,

중복을 원하지 않는 경우:

~$ sed -n -e '/^1/p' -e '/,,$/p' f | uniq
1, p1, p2, p3, p4, p5, p6, p7
2, p9, p10,,
1, p1, p2, p3, p4, p5, p6, p7
2, p9, p10,,

awk를 사용하여 정규식을 다음과 결합합니다 ;.

~$ awk '/^1/;/,,$/' f
1, p1, p2, p3, p4, p5, p6, p7
2, p9, p10,,
2, p9, p10,,
2, p9, p10,,
1, p1, p2, p3, p4, p5, p6, p7
2, p9, p10,,

답변3

ORS원하는 형식으로 출력되도록 조건부로 설정할 수 있습니다.

awk '/^1/,/,,$/{ORS = /^1/? ", ": "\n"; print}' file
1, p1, p2, p3, p4, p5, p6, p7, 2, p9, p10,,
1, p1, p2, p3, p4, p5, p6, p7, 2, p9, p10,,

관련 정보