특정 패턴 뒤의 하위 문자열 분리

특정 패턴 뒤의 하위 문자열 분리

파일에 다음과 같은 줄이 있습니다.

<TD><TR> monogram ended in 1 </TD></TR>

monogram ended in는 항상 상수이지만 no 입니다 1. 숫자는 항상 변경되며 최대 3자리까지 가능합니다.

monogram ended in따라서 해당 문자열 다음에 나오는 숫자를 검색하고 가져오려면 명령이 필요합니다 .

누구든지 나를 도와주세요.

답변1

다음과 같이 사용할 수 있습니다 sed.

sed -n 's/.*monogram ended in \([0-9]*\).*/\1/p' filename
  • 다음을 사용하여 -n정상적인 출력을 억제할 수 있습니다.
  • ubstitute 명령은 s전체 줄( .*시작과 끝)을 로 바꿉니다 \1. 이는 내부 부분 \(\), 즉 숫자 입니다.
  • p플래그는 경기에서 교체 선수를 인쇄합니다.

답변2

grep의 GNU 구현에는 -P"Perl 호환 정규식"으로 설명된 정규식 세트를 활성화하는 옵션이 있습니다. 다음을 사용할 수 \K있으며 원하는 방식으로 출력을 줄이는 데 사용할 수 있습니다.

grep -Po 'monogram ended in \K\d+' filename
  • -P옵션을 사용하면 Perl 스타일 정규식을 사용할 수 있습니다.
  • -o옵션은 grep에게 (전체 라인 대신) 라인의 일치하는 부분만 출력하도록 지시합니다.
  • 정규식은 설명하는 줄과 일치합니다. 이 줄은 "로 끝나는 문자와 숫자의 조합입니다.
  • \K표현식은 grep에게 전체 정규식을 사용하여 줄을 일치시키도록 지시하지만 표현식 뒤에 오는 부분만 기록합니다.\K
  • 표현식이 \d+하나 이상의 숫자와 일치합니다.

위의 예에서는 일치하는 숫자를 세 개의 연속 숫자로 제한하지 않습니다. 이를 수행하려는 경우 가장 효율적인 표현은 다음과 같습니다.

grep -Po 'monogram ended in \K\d{1,3}(?!\d)' filename
  • 표현식이 \d{1,3}연속된 1자리, 2자리 또는 3자리 숫자와 일치합니다.
  • (?!\d)표현식은 숫자 뒤의 위치를 ​​확인하여 숫자(문자일 수도 있고 줄의 끝일 수도 있음)가 아닌지 확인하여 4개 이상의 연속 숫자가 있는 줄은 일치하지 않도록 합니다.

답변3

사용행복하다(이전 Perl_6)

raku -ne 'put $/ if m/ <?after "monogram ended in" \s > \d+ /;'   

유니코드 문자(강력한 내장 유니코드 지원 포함)를 처리해야 한다면 Raku가 좋은 선택입니다. 위의 내용이 인쇄됩니다 $/(Raku의 일치 변수 또는 $<>). 코드는 <?after … >각 줄이 하나와 일치한다고 가정하고 너비가 0인 정방향 전환 어설션( )을 사용하고 일치하지 않는 줄을 제거합니다.

일치하는 항목이 없는 빈 행을 원하면 다음 코드를 사용하세요.

raku -ne 'if m/ <?after "monogram ended in" \s > \d+ / {put $/} else {put ""};'  

Raku의 정규식 수량자를 사용하여 일치하는 숫자의 범위를 제한할 수 있습니다 **. 예를 들어, \d**1..3그렇지 않으면 <digits>**1..3길이가 1~3자리인 일치 항목만 반환합니다. 그러나 줄은 왼쪽에서 오른쪽으로 읽히기 때문에 3자리 이상의 일치하는 줄은 오른쪽 끝에서 잘립니다. 따라서 단순히 수량자를 추가하는 것만으로는 예상한 결과를 얻지 못할 수 있습니다. 이를 올바르게 수행하려면 숫자가 아닌 정규식 원자를 오른쪽 끝에 추가해야 합니다.

raku -ne 'put $<> if m/ <?after "monogram ended in " > <digit>**1..3 <!digit> /;' 

입력 예:

<TD><TR> monogram ended in 1 </TD></TR>
<TD><TR> duogram ended in 2 </TD></TR>
<TD><TR> monogram ended in 4444 </TD></TR>

출력 예(최종 코드 예):1

https://raku.org

답변4

입력이 XML이고 노드가 아래와 같이 올바른 방식으로 정렬되었다고 가정합니다.

<?xml version="1.0"?>
<root>
  <TR>
    <TD>monogram ended in 1</TD>
  </TR>
</root>

(및 노드의 시작 태그는 질문에서 교체됩니다. TR) 그런 다음 XML 파서를 사용하여 다음과 같이 노드의 하위 노드 뒤에 나타나는 값 부분을 추출할 수 있습니다.TDxmlstarletmonogram ended inTDTR

xmlstarlet sel --template \
    --match    '//TR/TD[starts-with(text(),"monogram ended in ")]' \
    --value-of 'substring-after(text(),"monogram ended in ")' -nl file.xml

TDTR노드의 직계 하위이고 string 으로 시작하는 값을 갖는 각 노드 에 대해 monogram ended in해당 문자열 다음의 텍스트를 추출한 다음 개행 문자를 추가합니다.

다음과 같은 샘플 문서의 경우:

<?xml version="1.0"?>
<root>
  <TR>
    <TD>monogram ended in 1</TD>
    <TD>monogram ended in 2</TD>
    <TD>monogram ended in 3</TD>
  </TR>
  <TR>
    <TD>monogram ended in A</TD>
    <TD>monogram ended in B</TD>
    <TD>monogram ended in C</TD>
  </TR>
</root>

...명령이 출력됩니다

1
2
3
A
B
C

관련 정보