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