하위 문자열을 추출해야 하는 문자열이 있는데 정규식 끝이 반복됩니다. 많은 언어의 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접근 방식 (필요PCRE지원하다):
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
그러면 문자열이 세 부분(첫 번째 부분 전, 2 부분 뒤, 그리고 '문자열' 사이)으로 절단됩니다. -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