sed - 두 번째 모드에서 텍스트 블록을 인쇄하는 방법은 무엇입니까?

sed - 두 번째 모드에서 텍스트 블록을 인쇄하는 방법은 무엇입니까?

두 개의 테이블이 포함된 HTML 페이지가 있습니다.

두 테이블 모두 동일한 레이블 " <table role="grid">"로 시작하며 두 번째 테이블 코드를 표시하고 싶습니다.

현재는 첫 번째 항목만 표시하는 것으로 알고 있습니다.

sed -n '/<table role=\"grid\">/,/<\/table>/p' page.html

당신은 무엇을 할 것인가?

답변1

이것은 효과가 있지만 더 간단한 해결책이 있어야 한다고 확신합니다.

sed -n '/<table role=\"grid\">/{
 x
 /^$/b
 x
:loop
 p
 /<\/table>/q
 n
 b loop
}'

일치하는 경우 table행이 예약된 공간으로 바뀌고(x) 이전에 예약된 콘텐츠가 비교됩니다. 처음에는 비어 있으므로(/^$/) 스크립트 끝으로 분기합니다(b). 다음번에는 예약이 비어 있지 않습니다(첫 번째 테이블 행이 있음). 따라서 스왑(x)을 실행 취소하고 종료(q) 시 테이블 끝이 일치할 때까지 라인(p)을 인쇄하는 루프를 시작합니다. 매번 다음 행(n)을 얻고 루프 레이블로 다시 분기됩니다.

awk에서는 훨씬 더 간단합니다.

awk '/<table role=\"grid\">/,/<\/table>/ { if(n==1)print }
     /<\/table>/ { n++ }'

답변2

나는 다음을 사용할 것이다 perl:

perl -ne 'if(/<table role="grid">/){$i++;$k=1} 
          if($i==2 && $k==1){print} 
          if(/<\/table>/){$k=0;}' file

설명하다

  • perl -ne: 입력 파일을 한 줄씩 읽고 주어진 스크립트를 -e각 줄에 적용합니다.
  • if(/<table role="grid">/){$i++;$k=1}: 행이 일치하면 <table role="grid">값에 1을 더하고 1로 $i설정합니다 .$k
  • if($i==2 && $k==1){print}: 현재 값이 $i2이고 현재 값이 $k1인 경우(따라서 a <table role="grid">와 a 사이에 있고 </table>이번이 두 번째인 경우 <table role="grid">) 현재 줄을 인쇄합니다.
  • if(/<\/table>/){$k=0;}: $k이 행이 일치하면 0으로 다시 설정됩니다 </table>.

관련 정보