Sed 정규식 문제입니다. ^부터 "까지 일치합니다.

Sed 정규식 문제입니다. ^부터 "까지 일치합니다.

sed오랫동안 정규 표현식을 사용하지 않았기 때문에 약간 녹슬었습니다. 조금 단순화하면 URL을 추출하려는 입력으로 다음 입력이 있습니다.

href="https://unix.stackexchange.com/"

^나는 regex101.com의 매우 유용한 도구를 사용하여 처음 에 와 첫 번째 사이의 모든 것을 제거하도록 표현식을 최적화했습니다 ".

s/^.*="//

=그러나 나는 이 플래그 에 의존하고 싶지 않기 때문에 이것은 내가 원하는 것이 아닙니다 . 그러나 표현식을 다음과 같이 수정하면:

s/^.*"//

마지막 과 마지막 ^사이의 모든 항목 과 일치 "하고 첫 번째는 무시합니다.

분명히 여기에 나를 실망시키는 뭔가가 빠져 있지만 도움을 주시면 대단히 감사하겠습니다.

Arch64에서 Ubuntu 21.04를 실행합니다.

답변1

당신이 놓친 것은 .*일치 입니다탐욕스럽게, 가능한 한 많은 문자를 소비합니다( "마지막 문자까지 포함).

"제외 "사이의 모든 것"을 사용 하거나 [^"]*Perl과 같이 탐욕스럽지 않은 수정자를 제공하는 정규식 엔진으로 전환할 수 있습니다..*?

$ printf '%s\n' 'href="https://unix.stackexchange.com/"' | sed 's/^[^"]*"//'
https://unix.stackexchange.com/"

$ printf '%s\n' 'href="https://unix.stackexchange.com/"' | perl -pe 's/^.*?"//'
https://unix.stackexchange.com/"

OTOH, 정말로 원하는 것이 기본 URL이라면 첫 번째 참조와 마지막 참조 사이의 모든 것을 일치 및 캡처하고 역참조를 사용하여 다시 바꿀 수 있습니다.

$ printf '%s\n' 'href="https://unix.stackexchange.com/"' | sed 's/^[^"]*"\(.*\)"/\1/'
https://unix.stackexchange.com/

엄밀히 말하면, 이니셜은 ^[^"]*더 이상 욕심이 없을 필요가 없으며, ^.*이 경우 대체될 수 있습니다. 왜냐하면 정규식 전체가 "두 번째와 일치하는 동안 첫 번째를 사용할 수 없기 때문입니다(그리디하게 만들면 욕심이 없는 필수 역추적이 발생할 수 있음). .

답변2

cut이런 종류의 작업이 고안된 이유는 다음과 같습니다.

$ cut -d'"' -f2 file
https://unix.stackexchange.com/

답변3

모든 것을 일치시킬 수 있습니다첫 번째 "그리고:

sed 's/^[^"]*"//'

^이것은 줄 시작 부분부터 여러 (0개 이상 *) 문자 와 일치합니다.아니요큰따옴표( [^"]) 다음에 큰따옴표가 옵니다 ".

답변4

사용 gawk:

awk '{print gensub(/(^.*")(.*")/, "\\2", "g");}' input

이 명령에서 gawk내장 gensub()함수는 backreference()를 사용하여 모든 캡처 그룹을 두 번째 캡처 그룹으로 바꿉니다 \\2.

뒤따르는 따옴표를 제거하려면 명령을 다음과 같이 변경할 수 있습니다.

awk '{print gensub(/(^.*")(.*)(")/, "\\2", "g");}' input

관련 정보