텍스트 줄의 문자열 앞/뒤에 Grep 변수 번호

텍스트 줄의 문자열 앞/뒤에 Grep 변수 번호

텍스트 줄에서 숫자를 찾고 싶습니다.

cat log.txt | grep "License term"

01/01/2024:00:30 License term is 123 days.

나는 이것에서 "마이너스"를 분리하고 싶습니다. 키워드 일치 전후에 단어를 에코하는 방법이 있습니까? ""is" 다음에 문자열을 출력합니다" 또는 ""days" 전에 문자열을 출력합니다"처럼요?

아마 똑같을 것 같지만, 앞으로는 바뀔 수도 있습니다. (로그 항목에 대한 서식이나 기타 텍스트가 추가됩니다)

답변1

다음 명령은 정규식과 일치하는 모든 줄 , 즉 하위 문자열이 포함된 모든 줄 , 선택적인 양의 정수, 줄 끝에 하위 문자열이 뒤따르는 모든 sed줄을 찾습니다 . 이러한 라인이 발견되면 전체 라인을 정수로 대체하고 수정된 라인을 출력하여 요청한 번호를 효과적으로 추출합니다.log.txt.*License term is \([0-9]*\) days\.$License term isdays.

sed -n 's/.*License term is \([0-9]*\) days\.$/\1/p' log.txt

또 다른 방법은 을 사용하는 것입니다 awk. 다음은 문자열이 포함된 줄만 일치시킨 License term다음 해당 줄에서 두 번째 공백으로 구분된 단어를 출력하는 약간 다른 접근 방식입니다.

awk '/License term/ { print $(NF-1) }' log.txt

분명히 문자열이 포함된 줄에서 공백으로 구분된 다섯 번째 필드를 제거하기 위해 와 grep결합 할 수도 있습니다 .cutLicense term

grep -F 'License term' log.txt | cut -d ' ' -f 5

여기서는 정규식 대신 문자열을 사용하여 검색하고 있음을 나타내기 위해 grep해당 옵션을 사용하고 있습니다.-F

답변2

GNU에서는 및 옵션을 grep사용할 수 있습니다 . 이는 각각 "줄에서 일치하는 부분만 인쇄" 및 "Perl 호환 정규 표현식 사용"을 의미합니다. PCRE의 경우 "지금까지 일치하는 항목을 모두 삭제합니다"라는 의미로 이를 사용할 수 있습니다 . 이 모든 것을 결합하면 다음과 같은 결과를 얻을 수 있습니다.-o-P\K

$ grep -oP 'License term is \K\d+' log.txt 
123

물론 이것이 일관되게 작동할지 여부는 그 안에 무엇이 있는지에 따라 다르지만 log.txt귀하의 예에서는 작동합니다.

답변3

pcre2grep(또는 이전 버전 ) 과 함께 pcregrep:

pcre2grep -xo1 '\d\d/\d\d/\d\d\d\d:\d\d:\d\d License term is (\d+) days\.' < log.txt

행은 보수적으로 일치하여 실제로 패턴과 일치하는 행만 선택하고 x거기에서 첫 번째o 캡처링 그룹 과 일치하는 숫자가 출력됩니다.1

p또는 Perl( in pcre2grep) 과 동일합니다 .

perl -lne '
  print $1 if m{^\d\d/\d\d/\d\d\d\d:\d\d:\d\d License term is (\d+) days\.$}
  ' < log.txt

답변4

사용행복하다(이전 Perl_6)

~$ raku -ne '.put if s/ .* "License term is " (<[0..9]>*) " days." $/$0/;'  log.txt   

#OR:

~$ raku -ne '.put if s/ .* License \s term \s is \s (<[0..9]>*) \s days \. $/$0/;'  log.txt

#OR:

~$ raku -ne '.put if s/ .* License <.ws> term <.ws> is <.ws>  (<[0..9]>*) <.ws> days \. $/$0/;'  log.txt

또는:

~$ raku -ne 'if /License \s term/ { put .words[4] };'  log.txt

#OR:

~$ raku -ne 'put .words[4]  if /License \s term/;'   log.txt

또는:

~$ raku -e '$0.put for lines.match(/ "License term is "  ( \d+ ) /);'  log.txt 

#OR:

~$ raku -e '.put for lines.match(/ "License term is "  ( \d+ ) /);'  log.txt  

Raku로 작성된 답변은 이미 게시된 우수한 답변과 여러 면에서 유사합니다 sed. awk처음 두 답변 세트는 -ne자동 인쇄되지 않는 한 줄씩 플래그를 사용합니다. 첫 번째 그룹에서는 s///이 양식을 사용하십시오 . 두 번째 그룹에서는 words공백을 분할하는 데 Raku의 루틴이 사용됩니다. 마지막 답변 세트에서 Raku에는 lines하위 키를 찾거나 반환하는 루틴이 있습니다 match.

입력 예:

#dummy_line followed by blank line

01/01/2024:00:30 License term is 123 days.
#dummy_line

예제 출력:

123

Raku 정규식 엔진을 사용하면 캡처 태그와 미리보기/뒤돌아보기도 사용할 수 있습니다. 자세한 내용은 아래 첫 번째 링크를 참조하세요. 또한 <[0..9]>ASCII 숫자 또는 \dASCII + 유니코드 숫자를 캡처하도록 선택할 수 있습니다 .

https://docs.raku.org/언어/regexes#Regexes
https://raku.org

관련 정보