"시작 모드" - "중지 모드" 쌍이 처음 발생한 후 텍스트를 인쇄하려면 어떻게 해야 합니까?

"시작 모드" - "중지 모드" 쌍이 처음 발생한 후 텍스트를 인쇄하려면 어떻게 해야 합니까?

여러 인증서가 포함된 파일이 있습니다.

-----BEGIN CERTIFICATE-----
AAAAAAA
AAAAAAA
AAAAAAA
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
BBBBBBB
BBBBBBB
BBBBBBB
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
CCCCCCC
CCCCCCC
CCCCCCC
-----END CERTIFICATE-----

AB C안에 글씨가 있는 걸 잘라서 그냥 ... n증명서 만 받고 싶어요 .

그것은 매우 유사하다이 문제이 작업을 수행할 수 있는 휴대용 방법이 있었으면 좋겠습니다. sed가능하면 와 함께 사용하는 것이 좋지만, awk불가능할 경우에는 사용 가능합니다 sed.

첫 번째 발생 이외의 특정 값까지 sed를 인쇄하는 방법이 있습니까?

답변1

입력이 올바른 형식의 인증서 파일인 경우(예제와 같이) 제가 생각할 수 있는 가장 쉬운 방법은 다음 명령을 사용하는 것입니다 awk.

awk '$0=="-----BEGIN CERTIFICATE-----" {n++} n>1' test.cert 

n이는 현재 줄( )이 "시작 패턴"과 정확하게 일치할 때마다 $0카운터 변수를 증가시킵니다 . "겉보기에 잘못된" 부울 표현식이 n>1true인 경우, 즉 시작 패턴의 두 번째 발생부터 시작하면 현재 행이 인쇄됩니다. awk초기화되지 않은 변수는 0(또는 사용 컨텍스트에 따라 빈 문자열)으로 처리되므로 n섹션에서 명시적으로 초기화할 필요가 없습니다.0BEGIN

입력 문서가 손상되면 상황이 더 복잡해집니다. 즉, 끝 패턴과 잘못 일치하는 시작 패턴이 포함되거나 그 반대의 경우도 마찬가지입니다.

답변2

@AdminBee 답변이 올바른 접근 방식이지만 생략하고 싶은 부분이 확실하다면첫 번째sed다음과 같이 할 수도 있습니다.

sed -n '/^-*END CERTIFICATE-*$/!d;:a n;p;ba' file

또는 여러 줄로 이식 가능한 방식으로:

sed -n '
    /^-*END CERTIFICATE-*$/!d;:a
    n;p;ba
' file

sed첫 번째 줄을 찾을 때까지 모든 줄을 삭제한 다음 -----END CERTIFICATE-----다른 모든 줄을 먹고 인쇄하는 루프를 만듭니다.

답변3

정규식 /BEGIN/ 및 /END/를 필수로 변경해야 합니다.

awk '
/BEGIN/,/END/{
  if ( /END/ && !f++ ) next
}f
' file

perl흡연 모드( -0777)

perl -0777 -pe '
  my($b,$e) = map { quotemeta s/$/ CERTIFICATE/r } qw(BEGIN END);
  my($B,$E) = map { qr{^-+ $_ -+\n}mx } ($b,$e);
  my $re = qr{$B (?s:.*?) $E}mx;
  substr($_,0,$+[0],"") if m{$re}m;
' file

GNU sed 편집기

sed -ne 's/\n//;t2
  /BEGIN/!{$!N;D;}
  :1;n;/END/!b1
  n
  :2;$!{N;P;G;D;}
  p
' file

csplit여기서는 Linux 유틸리티도 사용할 수 있습니다. 먼저 END 라인 주위에 입력 파일을 청크합니다. 그런 다음 BEGiN 앞에 END가 나타날 경우 첫 번째 파일 또는 두 개의 파일을 삭제합니다.

csplit -sz file '/END/+1' '{*}'
for f in xx*;do
  sed -n '/BEGIN/,/END/!d;$Q1' $f
  status=$?; rm -- "$f"
  [ " $status" = ' 1' ] && break
done
printf '%s\n' xx* | xargs -r cat

관련 정보