Quartus가 생성한 보고서 파일에는 다음과 같은 여러 "테이블"이 있습니다.
+---------------------+
; Section1 Title ;
+---------------------+
Miscellaneous text
+-----------------+
; Table1 Header ;
+--------+--------;
; Field1 ; Field2 ;
; Field3 ; Field4 ;
+--------+--------+
Table notes
+------------------------+
; Table2 Header ;
+---------------+--------;
; Longer Field1 ; Field2 ;
; Longer Field3 ; Field4 ;
+---------------+--------+
+---------------------+
; Section2 Title ;
+---------------------+
Miscellaneous text
참고: 섹션과 표 사이에는 항상 빈 줄이 있습니다.
아래와 같이 "헤더"와 일치하는 항목을 기반으로 완전한 테이블을 인쇄할 수 있기를 원합니다.
+-----------------+
; Table1 Header ;
+--------+--------;
; Field1 ; Field2 ;
; Field3 ; Field4 ;
+--------+--------+
Table notes
현재 우리는 grep의 다음 조합을 사용하여 시작 테이블 행을 인쇄하고 sed를 사용하여 나머지를 인쇄하고 있지만 sed만 사용하면 이 모든 작업을 수행할 수 있을 것 같습니다.
grep -h -B 1 "; Table1 Header" quartus.rpt | grep -v "; Table1 Header"
sed -n '/; Table1 Header/,/^$/p' quartus.rpt
답변1
awk를 사용하십시오.
$ awk -v RS= '/Table1 Header/' file
+-----------------+
; Table1 Header ;
+--------+--------;
; Field1 ; Field2 ;
; Field3 ; Field4 ;
+--------+--------+
Table notes
답변2
Perl의 단락 모드( -00
)는 입력(표준 입력 및/또는 파일)을 한 번에 한 단락씩 읽는 데 유용합니다. 단락은 다음 빈 줄까지 확장되는 텍스트 블록입니다. 단락 경계는 하나 이상의 빈 줄입니다.
예를 들어:
$ perl -00 -ne 'print if /Table1 Header/' quartus.rpt
+-----------------+
; Table1 Header ;
+--------+--------;
; Field1 ; Field2 ;
; Field3 ; Field4 ;
+--------+--------+
Table notes
그러면 "Table1 Title" 패턴과 일치하는 모든 단락이 인쇄됩니다. 패턴은 Perl 정규식이므로 필요한 만큼 간단하거나 복잡할 수 있습니다. man perlre
자세히보다.
그런데, 표뿐만 아니라 전체 섹션을 인쇄하려면 다음을 수행하면 됩니다.
$ perl -00 -ne 'if (/Section/) { $match = /Section1/ ? 1 : 0 }; print if $match' quartus.rpt
+---------------------+
; Section1 Title ;
+---------------------+
Miscellaneous text
+-----------------+
; Table1 Header ;
+--------+--------;
; Field1 ; Field2 ;
; Field3 ; Field4 ;
+--------+--------+
Table notes
+------------------------+
; Table2 Header ;
+---------------+--------;
; Longer Field1 ; Field2 ;
; Longer Field3 ; Field4 ;
+---------------+--------+
영어: 현재 단락이 "Section"과 일치하는 경우 $match 변수는 단락이 "Section1"과 일치하면 1로 설정되고 일치하지 않으면 0으로 설정됩니다. $match가 true(0이 아님)로 평가되면 모든 단락을 인쇄합니다.
다음은 리터럴 문자열 "Section"이 일치시키려는 패턴의 일부가 아닌 경우 더 유용할 수 있는 또 다른 보다 일반적인 변형입니다.
$ perl -00 -ne '$match = 1 if /Section1/;
$match = 0 if /Section2/;
print if $match' quartus.rpt
그러면 "Section1"과 일치하는 단락부터 시작하여 모든 단락이 인쇄됩니다.하지만 포함하지 않습니다"Section2"가 포함된 섹션입니다. 즉, 인쇄는 "Section1"에서 열리고 "Section2"에서 닫힙니다.
답변3
내 솔루션은 여러분이 원하는 것보다 더 바로크적으로 보일 수 있지만 sed에서 전체 처리를 수행하고 원하는 출력을 생성합니다.
복잡하기 때문에 bash에서 oneliner를 사용하는 것보다 sed 스크립트에 넣는 것이 더 쉽습니다.
table-extract.sed
먼저 다음을 내 컴퓨터에서 호출하는 파일에 넣습니다 .
#! /bin/sed -nf
# Label to loop back to after each line is checked
:search_for_table_start
# This stanza holds each line in case the next line is a matching header.
/; Table1 Header/!{
h; n
}
# This stanza finds a matching header and prints it along with the preceding table delimiter.
/; Table1 Header/{
x; p; x; p
b search_for_table_end
}
# Go back to start of this loop
b search_for_table_start
# Label to loop back to while printing the rest of the table
:search_for_table_end
# This stanza gets and prints each line while we haven't found the end of the table yet.
/^$/!{
n; p
}
# This stanza finds the end of the table and quits.
/^$/{
q
}
# Go back to start of the print loop
b search_for_table_end
실행 가능하게 만드세요:chmod +x table-extract.sed
OP MWE의 입력을 사용하여 예제를 실행합니다.
$ ./table-extract.sed quartus.rpt
+-----------------+
; Table1 Header ;
+--------+--------;
; Field1 ; Field2 ;
; Field3 ; Field4 ;
+--------+--------+
Table notes
특히 sed에 대한 경험이 있는 경우 스크립트의 주석이 충분히 설명이 되기를 바랍니다. 기본적으로 sed에는 예약된 공간과 패턴 공간이라는 개념이 있습니다. 나는 예비 공간을 사용하여 일치하는 헤더 이름이 발견될 때까지 "이전 행"을 걸어두어 예비 공간을 +-------+
테이블 상단에 유지할 수 있습니다.
헤더를 찾아 인쇄한 후 스크립트는 두 번째 루프로 이동하여 종료하기 전에 테이블의 나머지 부분을 인쇄합니다.
답변4
단일 sed 명령을 사용하여 "헤더" 일치를 기반으로 전체 테이블을 인쇄할 수 있습니다. 다음 명령은 "Table1 Header" 일치 항목을 기반으로 테이블 제목 및 설명을 포함한 전체 테이블을 인쇄합니다.
sed -n '/Table1 Header/,/^$/p' quartus.rpt
이 명령은 sed 명령을 사용하여 "quartus.rpt" 파일에서 "Table1 Header" 패턴을 검색합니다. -n 옵션은 sed의 기본 출력을 억제하고 p 플래그는 sed에게 패턴과 일치하는 행만 인쇄하도록 지시합니다. ,/^$/ 부분은 sed에게 빈 줄이 나타날 때까지(^$ 정규식으로 표시됨) 줄을 계속 인쇄하도록 지시합니다.