예를 들어 Debian 또는 Debian 파생 시스템의 도구를 사용하면 N*
빈 문자열과 일치하는 다음과 같은 정규 표현식이 sed에서 일치할 수 있습니다.
$ echo 'Hello' | sed 's/N*/ xx&xx /g'
xxxx H xxxx e xxxx l xxxx l xxxx o xxxx
xxxx
이는 각 문자열 문자 앞의 빈 일치(즉, 사이에 문자가 없는 문자열)의 올바른 결과입니다 xx&xx
( 에서 6회 Hello
. 후행 줄 바꿈은 계산되지 않으며 일치하지 않습니다).
xx
그리고 문자(또는 문자 그룹)가 일치하면 및 사이에 표시됩니다 xx
.
$ echo 'Hello' | sed 's/e*/ xx&xx /g'
xxxx H xxexx l xxxx l xxxx o xxxx
그러나 grep의 동일한 정규식은아니요빈 문자열과 일치합니다:
$ echo 'Hello' | grep -o 'N*'
하지만 인쇄할 거예요오직비어 있지 않은 일치:
$ echo 'Hello' | grep -o 'e*'
e
정규식 일치를 피하기 위해 grep에 추가 내부 규칙이 있습니까 empty
?
답변1
grep -o
grep --help
다음 과 같이 기록됨
-o, --only-matching show only nonempty parts of lines that match
그리고설명서에~처럼
일치하는 줄의 일치하는(비어 있지 않은) 부분만 인쇄하며, 각 부분은 별도의 출력 줄에 표시됩니다.
그렇습니다. 추가 규칙이 있습니다 grep -o
. 일치 항목이 비어 있지 않은 경우에만 출력됩니다.
에서는 echo 'Hello' | grep -o 'N*'
정규 표현식이 일치하지만(반환 코드를 보거나 사용하여 알 수 있음 echo 'Hello' | grep 'N*'
) 일치 항목이 비어 있으므로 아무것도 출력되지 않습니다.
답변2
길이가 0인 문자열 일치의 동작은 코드에서 특별한 경우일 수도 있고 아닐 수도 있습니다. 예를 들면 sed
아니지만perl
$ echo aabb | sed 's/a*/X/g'
XbXbX
$ echo aabb | gsed 's/a*/X/g'
XbXbX
$ echo aabb | perl -ple 's/a*/X/g'
XXbXbX
행동은 vi가 역사적으로 어떻게 행동했는지에 따라 달라질 수 있습니다.깊이에서 볼 수 있듯이 ex/ex_subst.c
:
/*
* !!!
* It's possible to match 0-length strings -- for example, the
* command s;a*;X;, when matched against the string "aabb" will
* result in "XbXbX", i.e. the matches are "aa", the space
* between the b's and the space between the b's and the end of
* the string. There is a similar space between the beginning
* of the string and the a's. The rule that we use (because vi
* historically used it) is that any 0-length match, occurring
* immediately after a match, is ignored. Otherwise, the above
* example would have resulted in "XXbXbX". Another example is
* incorrectly using " *" to replace groups of spaces with one
* space.
(또 다른 문제는 너비가 0인 일치 항목이 절대 일치하지 않는다는 점입니다. 이를 방지하기 위해 "다음 문자로 이동합니다..." 코드가 추가될 수 있다고 확신합니다.뒤쪽에누군가의 CPU가 몇 번 100%에 도달했고 그의 손바닥이 이마에 닿았습니다. )
BSD와 GNU는 모두 표현식 ed
에 실패하므로 s/a*/X/g
특이한 동작 ex-vi
은 sed
?
$ echo aabb > foo
$ ed foo
5
s/a*/X/g
?
s/a*/X
Xbb
Q
답변3
$ echo 'Hello' | grep -o 'N*'
$ echo $?
0
그것하다종료 상태로 표시된 대로 이 입력 줄의 빈 부분 문자열과 일치합니다. (예를 들어 다른 모드를 사용하면 N
stdout에서는 아무것도 얻지 못하지만 종료 상태는 1
,failure입니다.)
-o
그러지 않도록인쇄빈 일치 항목이 있지만 정규 표현식이 입력 행과 일치하는지 여부와는 아무런 관련이 없습니다. (예, 차이점을 알 수 있습니다. 빈 문자열 일치를 인쇄하면 각 일치 후에 줄 바꿈을 인쇄하므로 프롬프트 앞에 빈 줄이 있습니다. 또는 각 일치에 대해 하나씩 6이 됩니다.)
그렇지 않은 경우 -o
일치하는 전체 줄을 인쇄합니다.
$ echo 'Hello' | grep 'N*' # same as grep '' empty pattern
Hello