"something_something_something"과 같은 문자열이 있습니다.
이제 문자열은 다음 패턴을 가져야 합니다.^[a-zA-Z0-9](-*[a-zA-Z0-9])*
패턴과 일치하지 않는 문자열의 모든 문자를 바꾸는 방법은 무엇입니까?
내 예를 들어, 나는 다음을 수행해야 합니다:
somethingsomethingsomething
나는 그것을 시도했지만 sed -n '/^[a-zA-Z0-9](-*[a-zA-Z0-9])*/p'
성공하지 못했습니다.
답변1
첫째, sed -E
패턴이 확장 정규식(ERE)으로 해석되고 일반 괄호가 그룹화에 사용되도록 해야 합니다. 기본적으로 sed의 패턴은 BRE(Basic Regular Expressions)이며 \(
및 를 사용해야 합니다 \)
.
둘째, sed -n '/.../p'
작동하지만 부분적으로 일치하는 경우 전체 줄을 인쇄합니다. 패턴도 마지막에 고정된 경우 전체 행을 삭제하는 것이 유용합니다.
패턴에 맞지 않는 부분을 제거하려면 다음과 같이 하세요.
sed -E -e 's/^([a-zA-Z0-9](-*[a-zA-Z0-9])*).*/\1/' input.txt
후행은 .*
전체 줄이 일치하는지 확인한 다음 모든 것이 첫 번째 캡처 그룹의 내용으로 대체됩니다. input 의 경우 패턴의 주요 부분과 일치하지 않는 것으로 something_something_something
인쇄됩니다 .something
_
귀하의 패턴은 와 동일해 보입니다 [-a-zA-Z0-9]+
. 아마도 비슷한 것을 의미하는 것 같습니다 [a-zA-Z0-9]+(-[a-zA-Z0-9]+)*
. 이는 foo
또는 같은 문자열 과 일치해야 합니다 foo-bar-doodoo
(그러나 그렇지 않음 foo--bar
).
답변2
sNr(search n replacement)라는 쉘 변수에 저장된 또 다른 정규식을 작성하고 여기에 인용된 정규식 중 일부를 추가합니다.
확실하지 않은 문자는 해시 값(#)으로 대체됩니다.
sNr='
s@
\(
\(
\(
[a-zA-Z0-9](-*[a-zA-Z0-9])*
\)\{1,\}
#*
\)*
\)
[^a-zA-Z0-9#]
@\1#@
';
echo something_something_something |
sed -e "
:loop
${sNr//[$IFS]/}
tloop
"
something#something#something