From을 포함하는 파일에서 행 추출도착하다

From을 포함하는 파일에서 행 추출도착하다

단락/줄을 포함하는 "abc.txt" 파일이 있다고 가정합니다.

Hello, how are you doing sir? 
when are you going to arrive at the SBAHN platform to catch the train?

파일에서 "어떻게"에서 "잡기"까지 모든 문자를 추출하는 방법은 무엇입니까?

답변1

PCRE를 지원하는 버전이 있는 경우 grep다음 명령을 사용하여 원하는 작업을 수행할 수 있습니다.

$ grep -Pzo 'how.*\n.*catch' file 
how are you doing sir? 
when are you going to arrive at the SBAHN platform to catch

스위치:

  • -P- 할 수 있게 하다PCRE - Perl 호환 정규 표현식
  • -z- 일반적으로 파일 이름 뒤에 오는 문자 대신 0바이트(ASCII NUL 문자)를 출력합니다. 예를 들어, grep -lZ일반적인 개행 대신 각 파일 이름 뒤에 0바이트를 출력합니다. 이 옵션을 사용하면 파일 이름에 개행과 같은 특이한 문자가 포함된 경우에도 출력이 명확해집니다. 이 옵션은 find -print0, perl -0, 및 sort -z등의 명령과 함께 사용하여 xargs -0임의의 파일 이름, 개행 문자가 포함된 파일 이름도 처리할 수 있습니다.
  • -o- 일치하는 줄의 일치하는(비어 있지 않은) 부분만 인쇄하고, 각 부분은 별도의 출력 줄에 표시합니다.

답변2

작업에 적합한 도구는 다음과 같습니다.pcregrep

pcregrep -oM "how(.|\n)*catch" SPEC
  • pcregrep: Perl 호환 정규식을 사용하여 grep합니다.
  • -o: 패턴과 일치하는 선 부분만 표시
  • -M: 패턴이 여러 줄과 일치하도록 허용
  • (.|\n)*: 모든 문자 또는 개행 문자와 0회 이상 일치합니다.

탐욕스럽지 않은 버전을 원하면 ?다음을 추가하십시오 *.

pcregrep -oM "how(.|\n)*?catch" SPEC

답변3

사용sed

이 답변에서는 긴 줄을 처리할 수 있는 좋은 품질이 있다고 가정합니다 sed. 텍스트가 다음 파일에 있다고 가정합니다 file.

$ tr '\n' '\001' <file | sed -n -r 's/.*(how.*catch).*/\1\n/p' | tr '\001' '\n' 
how are you doing sir? 
when are you going to arrive at the SBAHN platform to catch

설명하다:

  • tr '\n' '\001' <file

    그러면 파일에서 읽고 file모든 개행 문자가 8진수 001 문자로 대체됩니다. 이는 입력을 단일 라인으로 변환하는 효과가 있습니다.

  • sed -n -r 's/.*(how.*catch).*/\1\n/p'

    이제 입력이 한 줄이므로 sed이 작업을 쉽게 처리할 수 있습니다. 위의 바꾸기 명령은 "how"에서 "catch"까지의 모든 텍스트를 캡처하여 표준 출력으로 인쇄합니다.

    이 옵션을 사용하면 -n정규식이 일치하지 않으면 아무것도 인쇄되지 않습니다. 따라서 입력에 시퀀스가 ​​없으면 how.*catch아무 것도 인쇄되지 않습니다.

  • tr '\001' '\n'

    그러면 8진수 001 문자가 다시 개행 문자로 변환됩니다.

sed8진수 001은 (a) 입력 파일에 없다고 확신하고 (b) 올바르게 처리할 수 있는 문자 로 대체될 수 있습니다 .

사용awk

$ awk '/how/{f=1;sub(/.*how/,"how")} /catch/{f=0;sub(/catch.*/,"catch");print} f' file
how are you doing sir? 
when are you going to arrive at the SBAHN platform to catch

설명하다:

  • /how/{f=1;sub(/.*how/,"how")}

    줄에 "how"라는 단어가 포함되어 있으면 "how" 앞의 모든 텍스트가 제거되고 플래그 변수가 f1로 설정됩니다.

  • /catch/{f=0;sub(/catch.*/,"catch");print}

    줄에 "catch"라는 단어가 포함되어 있으면 "catch" 뒤의 모든 텍스트가 삭제되고 플래그 변수가 f0으로 설정되며 수정된 줄이 인쇄됩니다.

  • f

    플래그가 1이면 이 다소 신비한 awk 명령으로 인해 해당 행이 인쇄됩니다. 이면 f==0아무것도 인쇄되지 않습니다.

답변4

sed텍스트가 파일의 일부가 아닌 경우 예제는 실패하며 아무것도 없는 대신 완전한 파일을 얻게 됩니다.

sed 대신 grep을 사용하십시오.

tr '\n' '\001' < file | grep -o -E 'how.*catch' | tr '\001' '\n' 

탐욕적 일치와 비탐욕적 일치도 문제이므로 "catch"가 2번째 줄에 있고 또 다른 "catch"가 5번째 줄에 있다면 비탐욕적 일치가 필요합니다.

이를 달성하는 방법은 여기에서 읽어보세요. 버전에 따라 많이 달라집니다 grep.

https://stackoverflow.com/questions/3027518/non-greedy-grep

관련 정보