sed를 사용하여 문자열 패턴을 시퀀스로 교체

sed를 사용하여 문자열 패턴을 시퀀스로 교체

텍스트 파일의 문자열을 sed를 사용하여 1 2 3 4 5 6 7과 같은 일련의 숫자로 바꾸고 싶습니다.

이것은 내가 (검색 문자열 없이) 시도한 것이며 작동하는 것 같습니다.

for i in {1..5};do echo $(seq 1 $i); done

산출:

1
1 2
1 2 3
1 2 3 4
1 2 3 4 5

그러나 내가 이렇게 하려고 하면:

for i in {1..5};do sed -i "s/abc/$(seq 1 $i)/g" test; done

다음 오류가 발생합니다.

sed: -e expression #1, char 8: unterminated `s' command
sed: -e expression #1, char 8: unterminated `s' command
sed: -e expression #1, char 8: unterminated `s' command
sed: -e expression #1, char 8: unterminated `s' command

또한 대체 문자열을 괄호로 묶으려고 시도했지만 작동하지 않는 것 같습니다.

첫 번째 루프

for i in {1..5}

일부 매개변수를 대체하려는 파일 이름으로 대체될 glob입니다.

답변1

TL;박사:

이에 대해 몇 가지 방법이 있습니다. 귀하의 사례에 가장 적합한 방법은 다음과 같습니다.

for i in {1..5};do sed -i "s/abc/$(seq -s ' ' 1 $i)/g" test; done

즉, seq각 숫자를 구분하려면 공백이 필요합니다.

설명하다:

이러한 오류가 발생하는 이유는 출력 때문입니다.

seq 1 5

아니요:

1 2 3 4 5

대신에:

1
2
3
4
5

첨부해주셔서$(seq 1 $i) 명령 대체일반적으로 큰따옴표 안에분사실행되지 않으므로 유틸리티가 출력하는 모든 줄 바꿈(마지막 줄 제외)은 seq그대로 유지됩니다.

따라서 실제 sed 명령은 다음과 같습니다.

sed -i "s/abc/1
2
3
4
5
/g" test

현재로서는 필수 Final 이 누락된 명령을 sed 제공하고 있기 때문에 이는 허용되지 않습니다 .s/abc/1/

An은 큰따옴표 안에 있지 않기 때문에 echo $(seq 1 5)인쇄하므로 쉘의 기본 동작에 따라 단어 분리가 발생합니다.1 2 3 4 5$(seq 1 5)

실제로 다음과 같이 예시 사례를 수정할 수 있습니다.

for i in {1..5};do sed -i "s/abc/$(echo $(seq 1 $i))/g" test; done

즉, 명령을 실행하여 (원본 seq 1 $i) 을 바꾸십시오.~에다른 명령은 ( echoa)를 대체합니다.

$(echo ...)명령 대체가 내부에 있기 때문에 큰따옴표 내에서도 작동합니다.서브쉘이것은아니요"I-am-inside-a-double-quote" 상태이므로 출력이 토큰화됩니다.seq ~ 할 것이다거기서 하세요.

답변2

출력을 임시 파일로 파이프한 다음 임시 파일을 원본 파일 위로 이동할 수 있습니다. 당신은요가능한한 번에 하나의 행만 작동하도록 의도되었으며, 이 경우 다음을 제거해야 합니다 g.

for i in {1..5}; do
    sed -e "s/abc/$(seq 1 $i)/" test > test.tmp
    mv test.tmp test
done

관련 정보