source

sed/grep을 사용하여 두 단어 사이에 텍스트를 추출하는 방법은 무엇입니까?

lovecheck 2023. 4. 17. 21:59
반응형

sed/grep을 사용하여 두 단어 사이에 텍스트를 추출하는 방법은 무엇입니까?

문자열의 두 단어 사이에 모든 것을 포함하는 문자열을 출력하려고 합니다.

입력:

"Here is a String"

출력:

"is a"

사용방법:

sed -n '/Here/,/String/p'

엔드포인트를 포함하지만 포함시키고 싶지 않습니다.

GNU grep는 긍정과 부정의 예측 및 룩백도 지원합니다.이 경우 명령어는 다음과 같습니다.

echo "Here is a string" | grep -o -P '(?<=Here).*(?=string)'

가 여러 개 있는 경우Here그리고.string첫 번째부터 일치시킬지 여부를 선택할 수 있습니다.Here그리고 마지막string개별적으로 매치할 수도 있습니다.regex의 경우 gready match(제1의 경우) 또는 non-greedy match(제2의 경우)라고 부릅니다.

$ echo 'Here is a string, and Here is another string.' | grep -oP '(?<=Here).*(?=string)' # Greedy match
 is a string, and Here is another 
$ echo 'Here is a string, and Here is another string.' | grep -oP '(?<=Here).*?(?=string)' # Non-greedy match (Notice the '?' after '*' in .*)
 is a 
 is another 
sed -e 's/Here\(.*\)String/\1/'

승인된 답변은 이전일 수 있는 텍스트를 삭제하지 않습니다.Here또는 그 후String. 이것은 다음과 같습니다.

sed -e 's/.*Here\(.*\)String.*/\1/'

주요 차이점은 의 추가입니다..*직전에Here그 후String.

Bash에서만 문자열을 제거할 수 있습니다.

$ foo="Here is a String"
$ foo=${foo##*Here }
$ echo "$foo"
is a String
$ foo=${foo%% String*}
$ echo "$foo"
is a
$

PCRE 를 포함한 GNU GRE 가 있는 경우는, 제로 폭의 어설션을 사용할 수 있습니다.

$ echo "Here is a String" | grep -Po '(?<=(Here )).*(?= String)'
is a

여러 줄의 오커리가 있는 긴 파일이 있는 경우 먼저 숫자 줄을 인쇄하는 것이 유용합니다.

cat -n file | sed -n '/Here/,/String/p'

GNU awk를 통해

$ echo "Here is a string" | awk -v FS="(Here|string)" '{print $2}'
 is a 

으로 가득 차다.-P(syslog-regexp) 파라미터는\K이는 이전에 일치한 문자를 폐기하는 데 도움이 됩니다.이 경우 이전에 일치한 문자열은Here최종 출력에서 삭제되었습니다.

$ echo "Here is a string" | grep -oP 'Here\K.*(?=string)'
 is a 
$ echo "Here is a string" | grep -oP 'Here\K(?:(?!string).)*'
 is a 

출력을 다음과 같이 하려면is a아래를 시험해 보세요.

$ echo "Here is a string" | grep -oP 'Here\s*\K.*(?=\s+string)'
is a
$ echo "Here is a string" | grep -oP 'Here\s*\K(?:(?!\s+string).)*'
is a

2개의 s 명령어를 사용할 수 있습니다.

$ echo "Here is a String" | sed 's/.*Here//; s/String.*//'
 is a 

또, 동작합니다.

$ echo "Here is a StringHere is a String" | sed 's/.*Here//; s/String.*//'
 is a

$ echo "Here is a StringHere is a StringHere is a StringHere is a String" | sed 's/.*Here//; s/String.*//'
 is a 

이해하기sed지휘부, 차근차근 구축해야 합니다.

여기 당신의 원문이 있습니다.

user@linux:~$ echo "Here is a String"
Here is a String
user@linux:~$ 

제거해 보겠습니다.Here로 묶다.substition 옵션sed

user@linux:~$ echo "Here is a String" | sed 's/Here //'
is a String
user@linux:~$ 

이쯤에서, 제 생각엔, 제 생각엔String뿐만 아니라.

user@linux:~$ echo "Here is a String" | sed 's/String//'
Here is a
user@linux:~$ 

그러나 이것은 당신이 원하는 출력이 아닙니다.

두 sed 명령을 결합하려면-e선택

user@linux:~$ echo "Here is a String" | sed -e 's/Here //' -e 's/String//'
is a
user@linux:~$ 

도움이 되었으면 좋겠다

이 방법이 효과적일 수 있습니다(GNU sed).

sed '/Here/!d;s//&\n/;s/.*\n//;:a;/String/bb;$!{n;ba};:b;s//\n&/;P;D' file 

이것은 두 마커 사이의 텍스트의 각 표현을 나타냅니다(이 경우).Here그리고.String줄 바꿈)을 사용하여 텍스트 내에서 줄 바꿈을 유지합니다.

위의 모든 솔루션에는 문자열의 다른 부분에서 마지막 검색 문자열이 반복되는 결함이 있습니다.bash 함수를 쓰는 것이 가장 좋습니다.

    function str_str {
      local str
      str="${1#*${2}}"
      str="${str%%$3*}"
      echo -n "$str"
    }

    # test it ...
    mystr="this is a string"
    str_str "$mystr" "this " " string"

사용할 수 있습니다.\1(http://www.grymoire.com/Unix/Sed.html#uh-4) 를 참조해 주세요.

echo "Hello is a String" | sed 's/Hello\(.*\)String/\1/g'

괄호 안에 있는 내용은 다음과 같이 저장됩니다.\1.

문제가 있다.저장된 Claws Mail 메시지는 다음과 같이 포장되어 있으며 Subject 행을 추출하려고 합니다.

Subject: [SLC38A9 lysosomal arginine sensor; mTORC1 pathway] Key molecular
 link in major cell growth pathway: Findings point to new potential
 therapeutic target in pancreatic cancer [mTORC1 Activator SLC38A9 Is
 Required to Efflux Essential Amino Acids from Lysosomes and Use Protein as
 a Nutrient] [Re: Nutrient sensor in key growth-regulating metabolic pathway
 identified [Lysosomal amino acid transporter SLC38A9 signals arginine
 sufficiency to mTORC1]]
Message-ID: <20171019190902.18741771@VictoriasJourney.com>

이 스레드의 A2에 따르면 sed/grep을 사용하여 두 단어 사이에 텍스트를 추출하는 방법은 무엇입니까?일치하는 텍스트에 새 행이 포함되지 않는 한 아래 첫 번째 식은 "작동"합니다.

grep -o -P '(?<=Subject: ).*(?=molecular)' corpus/01

[SLC38A9 lysosomal arginine sensor; mTORC1 pathway] Key

수많은변종)을 .+?; /s; ... , , , , , , , , , , , , , , , , , , , 를 사용할 수 .

grep -o -P '(?<=Subject: ).*(?=link)' corpus/01
grep -o -P '(?<=Subject: ).*(?=therapeutic)' corpus/01
etc.

해결책 1

Per 다른 행에 있는 두 문자열 사이의 텍스트 추출

sed -n '/Subject: /{:a;N;/Message-ID:/!ba; s/\n/ /g; s/\s\s*/ /g; s/.*Subject: \|Message-ID:.*//g;p}' corpus/01

그러면

[SLC38A9 lysosomal arginine sensor; mTORC1 pathway] Key molecular link in major cell growth pathway: Findings point to new potential therapeutic target in pancreatic cancer [mTORC1 Activator SLC38A9 Is Required to Efflux Essential Amino Acids from Lysosomes and Use Protein as a Nutrient] [Re: Nutrient sensor in key growth-regulating metabolic pathway identified [Lysosomal amino acid transporter SLC38A9 signals arginine sufficiency to mTORC1]]                              

솔루션 2.*

설명: sed를 사용하여 새 회선을 교체하는 방법(\n)

sed ':a;N;$!ba;s/\n/ /g' corpus/01

줄바꿈을 공백으로 바꿉니다.

sed/grep를 사용하여 두 단어 사이에 텍스트를 추출하는 방법에 있는 A2를 연결하면 다음과 같은 결과가 나옵니다.

sed ':a;N;$!ba;s/\n/ /g' corpus/01 | grep -o -P '(?<=Subject: ).*(?=Message-ID:)'

그러면

[SLC38A9 lysosomal arginine sensor; mTORC1 pathway] Key molecular  link in major cell growth pathway: Findings point to new potential  therapeutic target in pancreatic cancer [mTORC1 Activator SLC38A9 Is  Required to Efflux Essential Amino Acids from Lysosomes and Use Protein as  a Nutrient] [Re: Nutrient sensor in key growth-regulating metabolic pathway  identified [Lysosomal amino acid transporter SLC38A9 signals arginine  sufficiency to mTORC1]] 

이 변형은 이중 공간을 제거합니다.

sed ':a;N;$!ba;s/\n/ /g; s/\s\s*/ /g' corpus/01 | grep -o -P '(?<=Subject: ).*(?=Message-ID:)'

부여

[SLC38A9 lysosomal arginine sensor; mTORC1 pathway] Key molecular link in major cell growth pathway: Findings point to new potential therapeutic target in pancreatic cancer [mTORC1 Activator SLC38A9 Is Required to Efflux Essential Amino Acids from Lysosomes and Use Protein as a Nutrient] [Re: Nutrient sensor in key growth-regulating metabolic pathway identified [Lysosomal amino acid transporter SLC38A9 signals arginine sufficiency to mTORC1]]

ripgrep

다음은 를 사용하는 예를 제시하겠습니다.

$ echo Here is a String | rg 'Here\s(.*)\sString' -r '$1'
is a

그다지 훌륭하지는 않지만 효과적인 솔루션은 다음과 같습니다.

$ echo 'Here is a String' | sed 's/Here/\n/g'| sed 's/String/\n/g'| sed -r '/^[[:space:]]*$/d'

is a

, ,에서는 합니다.Here is a String Here is a second String아,아,아,아,아,아,아,아,아,아,아,아,아.

$ echo 'Here is a String Here is a second String' | sed 's/Here/\n/g'| sed 's/String/\n/g'| sed -r '/^[[:space:]]*$/d'

is a
is a second

또는 다음과 같이 입력합니다.

$ echo 'Here is a String Here is a second String Here is last String' | sed 's/Here/\n/g'| sed 's/String/\n/g'| sed -r '/^[[:space:]]*$/d'

is a
is a second
is last

언급URL : https://stackoverflow.com/questions/13242469/how-to-use-sed-grep-to-extract-text-between-two-words

반응형