여러 인증서가 포함된 파일이 있습니다.
-----BEGIN CERTIFICATE-----
AAAAAAA
AAAAAAA
AAAAAAA
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
BBBBBBB
BBBBBBB
BBBBBBB
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
CCCCCCC
CCCCCCC
CCCCCCC
-----END CERTIFICATE-----
A
B
C
안에 글씨가 있는 걸 잘라서 그냥 ... n
증명서 만 받고 싶어요 .
그것은 매우 유사하다이 문제이 작업을 수행할 수 있는 휴대용 방법이 있었으면 좋겠습니다. sed
가능하면 와 함께 사용하는 것이 좋지만, awk
불가능할 경우에는 사용 가능합니다 sed
.
첫 번째 발생 이외의 특정 값까지 sed를 인쇄하는 방법이 있습니까?
답변1
입력이 올바른 형식의 인증서 파일인 경우(예제와 같이) 제가 생각할 수 있는 가장 쉬운 방법은 다음 명령을 사용하는 것입니다 awk
.
awk '$0=="-----BEGIN CERTIFICATE-----" {n++} n>1' test.cert
n
이는 현재 줄( )이 "시작 패턴"과 정확하게 일치할 때마다 $0
카운터 변수를 증가시킵니다 . "겉보기에 잘못된" 부울 표현식이 n>1
true인 경우, 즉 시작 패턴의 두 번째 발생부터 시작하면 현재 행이 인쇄됩니다. awk
초기화되지 않은 변수는 0(또는 사용 컨텍스트에 따라 빈 문자열)으로 처리되므로 n
섹션에서 명시적으로 초기화할 필요가 없습니다.0
BEGIN
입력 문서가 손상되면 상황이 더 복잡해집니다. 즉, 끝 패턴과 잘못 일치하는 시작 패턴이 포함되거나 그 반대의 경우도 마찬가지입니다.
답변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