sed를 사용하여 첫 번째 발생의 끝에서 멈추는 부분 문자열 추출

sed를 사용하여 첫 번째 발생의 끝에서 멈추는 부분 문자열 추출

하위 문자열을 추출해야 하는 문자열이 있는데 끝에 정규식이 반복됩니다. 많은 언어의 instr() 함수가 첫 번째 인스턴스를 반환하는 것처럼 sed가 정규식 끝의 첫 번째 인스턴스에서 멈추기를 원합니다. 예:

echo "This is a test some stuff I want string junk string end" | sed -n 's/.*\(.te.*ng\).*/\1/p' 
returns: test some stuff I want string junk string
I want to return: test some stuff I want string

답변1

grep방법 (요구폴리 메라 제 연쇠 반응지원하다):

s="This is a test some stuff I want string junk string end"
grep -Po 'te.*?ng' <<< $s

선택하다진주방법:

perl -ne 'print "$&\n" if /te.*?ng/' <<< $s

출력(두 방법 모두):

test some stuff I want string

  • .*?- ?이것은욕심이 없다일치 여부를 알려주는 수정자미니멀리스트 패션

답변2

두 단계로 수행합니다. 먼저 접두사를 제거한 다음(종료자가 접두사에 있는 경우) 접두사 뒤의 모든 항목을 제거합니다. 일치하는 항목이 없으면 T다음 명령을 사용하여 줄을 건너뜁니다.

echo "This is a test some stuff I want string junk string end" |
sed -n 's/.*\(.te.*ng\)/\1/; T; s/\(ng\).*/\1/p'

또는 일치하지 않는 행을 먼저 삭제한 다음 마음대로 교체를 수행하십시오.

echo "This is a test some stuff I want string junk string end" |
sed '/.*\(.te.*ng\)/!d; s/.*\(.te.*ng\)/\1/; s/\(ng\).*/\1/'

또는 일치하는 라인에서만 교체 및 최종 인쇄를 수행하십시오.

echo "This is a test some stuff I want string junk string end" |
sed '/.*\(.te.*ng\)/ { s/.*\(.te.*ng\)/\1/; s/\(ng\).*/\1/p; }'

답변3

귀하의 경우에는 cut 명령을 사용하는 것이 좋습니다

echo "I am a useful and I am a string. Did I mention that I'm a string?" | cut -d "string" -f1

그러면 문자열이 세 부분으로 절단됩니다(첫 번째 부분 전, 두 번째 부분 뒤, "문자열" 사이). -d""를 사용하면 절단기로 사용할 패턴을 선택할 수 있으며, -fNumber를 사용하면 원하는 부분을 선택할 수 있습니다. 사용. 문제: "문자열"이 삭제됩니다. 해결 방법:

String=`echo "I am a useful and I am a string. Did I mention that I'm a string?" | cut -d "string" -f1`
String="$(String) string"
echo $String

출력으로 정의된 $String 변수의 끝에 제거된 구분 기호 "문자열"을 추가합니다.

답변4

# 그리디 매칭을 수행하기 위해 POSIX sed를 사용하는 방법: "test .*? string"

sed -e '
   /test.*string/!d;      # non-interesting line
   /^test/s/string/&\
/;                        # append marker after the first substring "string"
   /\n/{P;d;}             # initial portion of pattern space is our result
   s/test/\
&/;D;                     # remove portion before the substring "test"
' yourfile

다른POSIX-라이이 방법은 패턴 공간의 끝에서 하위 문자열 "string"을 한 번에 하나씩 가져와서 하나만 남을 때까지(하위 문자열 "test" 다음) 가져오는 것입니다. 그런 다음 남은 것은 하위 문자열 "test"를 앞에 추가하는 것입니다.

sed -e '
   :loop
      s/\(test.*string\).*string.*/\1/
   tloop
   /^test/!s/test/\
&/;/\n/D
' yourfile

관련 정보