동일한 시퀀스를 다시 반복하지 않고 문자 시퀀스의 발생을 재귀 적으로 대체 할 수 있습니까?
sed
다음 시나리오에서와 같이 수행 하면 언급 된 출력을 얻을 수 있습니다.
$ echo XX | sed -e 's/XX/XoX/g'
XoX
$ echo XXX | sed -e 's/XX/XoX/g'
XoXX
$ echo XXXX | sed -e 's/XX/XoX/g'
XoXXoX
그러나 출력이 다음 동작을 따르기를 기대합니다.
입력:
XX
XXX
XXXX
예상 출력 :
XoX
XoXoX
XoXoXoX
sed만으로도 예상되는 동작을 수행 할 수 있습니까?
답변
넌 할 수있어:
> echo XXXX | sed -e ':loop' -e 's/XX/XoX/g' -e 't loop'
XoXoXoX
와:
-e ':loop'
: “루프”레이블 만들기-e 't loop'
: 이전 대체가 성공한 경우 “루프”레이블로 이동
답변
이 특별한 경우에 미리보기 또는 뒤에보기가 유용합니다. 나는 GNU sed
가 이것을 지원하지 않는다고 생각 합니다. 로 perl
:
perl -ne 's/X(?=X)/Xo/g; print;'
lookbehind와 lookahead를 다음 과 같이 사용할 수도 있습니다 .
s/(?<=X)(?=X)/o/g
어디:
(?<=X)
현재 위치 앞에 X가 있는지 확인하는 길이가 0 인 어설 션
(?=X)
인 긍정적 인 모습, 현재 위치 뒤에 X가 있는지 확인하는 길이가 0 인 어설 션입니다.
펄 원 라이너에서 사용 :
perl -pe 's/(?<=X)(?=X)/o/g' inputfile
어디:
-p
Perl이 현재 행을 암시 적으로 인쇄하여 프로그램 주위에서 루프를 가정합니다.
답변
루핑 답변은 원하는 것을하는 일반적인 방법입니다.
그러나 데이터의 경우 GNU를 사용한다고 가정하면 간단하게 수행 할 수 있습니다.
sed 's/\B/o/g'
\b
및 \B
옵션은 정규식 확장 :
\b
단어 경계, 즉 “단어”문자에서 “단어 이외”문자로의 전환 또는 그 반대로 전환\B
의 반대와 일치합니다\b
. 즉, “내부”단어의 격차. 이를 통해 단어 내부에 문자를 삽입 할 수 있지만 필요에 따라 외부에 삽입 할 수는 없습니다.
이것은 입력 문자가 실제로 모든 “단어”문자라고 가정합니다.
또는 GNU sed가 없거나 입력 문자가 모두 “단어”문자가 아닌 경우에도 반복없이 목표를 달성 할 수 있습니다.
sed 's/./&o/g;s/o$//'
이것은 단순히 o
모든 문자 뒤에 문자 를 배치 한 다음 o
문자열 에서 마지막 문자를 제거 합니다.
답변
이런 일을하기 위해 어떤 종류의 깃발이 있는지 확인했습니다.
그러한 행동이 있었더라도 자원을 많이 소비하게 될 것입니다.
그러나이 특정 사용 사례에서는 두 번만 표현식을 사용하여 필요한 기능을 수행 할 수 있습니다. 즉, 2 개의 반복되는 sed
표현.
echo XX | sed -e 's/XX/XoX/g' -e 's/XX/XoX/g' # outputs XoX
echo XXX | sed -e 's/XX/XoX/g' -e 's/XX/XoX/g' # outputs XoXoX
echo XXXX | sed -e 's/XX/XoX/g' -e 's/XX/XoX/g' # outputs XoXoXoX