문자를 sed로 재귀 적으로 바꾸는 방법은 무엇입니까?


13

동일한 시퀀스를 다시 반복하지 않고 문자 시퀀스의 발생을 재귀 적으로 대체 할 수 있습니까?

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만으로도 예상되는 동작을 수행 할 수 있습니까?

답변:


24

넌 할 수있어:

> echo XXXX | sed -e ':loop' -e 's/XX/XoX/g' -e 't loop'
XoXoXoX

와:

  • -e ':loop' : "루프"레이블 만들기
  • -e 't loop' : 이전 대체가 성공한 경우 "루프"레이블로 이동

10

이 특별한 경우에 미리보기 또는 뒤에보기가 유용합니다. 나는 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이 현재 행을 암시 적으로 인쇄하여 프로그램 주위에서 루프를 가정합니다.


5

루핑 답변은 원하는 것을하는 일반적인 방법입니다.

그러나 데이터의 경우 GNU를 사용한다고 가정하면 간단하게 수행 할 수 있습니다.

sed 's/\B/o/g'

\b\B옵션은 정규식 확장 :

  • \b 단어 경계, 즉 "단어"문자에서 "단어 이외"문자로의 전환 또는 그 반대로 전환
  • \B의 반대와 일치합니다 \b. 즉, "내부"단어의 격차. 이를 통해 단어 내부에 문자를 삽입 할 수 있지만 필요에 따라 외부에 삽입 할 수는 없습니다.

온라인으로 사용해보십시오 .

이것은 입력 문자가 실제로 모든 "단어"문자라고 가정합니다.


또는 GNU sed가 없거나 입력 문자가 모두 "단어"문자가 아닌 경우에도 반복없이 목표를 달성 할 수 있습니다.

sed 's/./&o/g;s/o$//'

이것은 단순히 o모든 문자 뒤에 문자 를 배치 한 다음 o문자열 에서 마지막 문자를 제거 합니다.

온라인으로 사용해보십시오 .


1
이것은 입력 문자열이 몇 개의 숫자로 구성 X되고 다른 것은 없다고 가정합니다. 다른 문자가 존재하면 두 솔루션 모두 실패합니다.
AnoE

@AnoE 두 번째 샘플에서는 Xby 의 간단한 교체로 고정 됩니다 .. 편집을 참조하십시오.
Digital Trauma

OP가 준 경우와 동일하지 않습니다. 그는 필요한 정확한 RE를 제공했습니다 (문자열에서 XX의 변경 발생). 당신의 버전은 그가 준 것과 정확히 같은 입력 문자열에 대한 결과와 동일한 결과를 제공합니다. 일반 입력 문자열이 아닙니다.
AnoE

4

이런 일을하기 위해 어떤 종류의 깃발이 있는지 확인했습니다.
그러한 행동이 있었더라도 자원을 많이 소비하게 될 것입니다.

그러나이 특정 사용 사례에서는 두 번만 표현식을 사용하여 필요한 기능을 수행 할 수 있습니다. 즉, 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
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.