[sed] 슬래시가 포함 된 문자열을 sed로 바꾸는 방법은 무엇입니까?

로컬로 개발 된 Visual Studio 프로젝트가 있습니다. 코드 파일은 원격 서버에 배포해야합니다. 유일한 문제는 포함 된 URL에 하드 코딩 된 것입니다.

프로젝트에 ? page = one 과 같은 URL이 포함되어 있습니다 . 링크가 서버에서 유효하려면 / page / one 이어야합니다 .

배포 전에 코드 파일의 모든 URL을 sed로 교체하기로 결정했지만 슬래시가 붙어 있습니다.

나는 이것이 꽤 좋은 해결책은 아니라는 것을 알고 있지만, 그것은 많은 시간을 절약 할 것입니다. 교체해야하는 총 문자열 수는 10 개 미만입니다. 확인해야하는 총 파일 수는 ~ 30입니다.

내 상황을 설명하는 예는 다음과 같습니다.

내가 사용하는 명령 :

sed -f replace.txt < a.txt > b.txt

모든 문자열을 포함하는 replace.txt :

s/?page=one&/pageone/g
s/?page=two&/pagetwo/g
s/?page=three&/pagethree/g

a.txt :

?page=one&
?page=two&
?page=three&

내 sed 명령을 실행 한 후 b.txt의 내용 :

pageone
pagetwo
pagethree

b.txt에 포함하고 싶은 것 :

/page/one
/page/two
/page/three



답변

가장 쉬운 방법은 검색 / 바꾸기 행에 다른 구분 기호를 사용하는 것입니다. 예 :

s:?page=one&:pageone:g

어떤 문자도 문자열의 일부가 아닌 분리 문자로 사용할 수 있습니다. 또는 백 슬래시로 이스케이프 처리 할 수 ​​있습니다.

s/\//foo/

로 대체 /됩니다 foo. 대체 문자열에서 어떤 문자가 발생할 수 있는지 모르는 경우 (예를 들어 쉘 변수 인 경우) 이스케이프 된 백 슬래시를 사용하려고합니다.


답변

s명령은 구분 기호로 모든 문자를 사용할 수 있습니다; 뒤에 나오는 모든 문자 s가 사용됩니다. 나는을 사용하기 위해 자랐다 #. 이렇게 :

s#?page=one&#/page/one#g


답변

sed에 대해 매우 유용하지만 덜 알려진 사실은 친숙한 s/foo/bar/명령이 슬래시뿐만 아니라 모든 구두점을 사용할 수 있다는 것입니다. 일반적인 대안은 s@foo@bar@문제를 해결하는 방법이 분명 해지는 것입니다.


답변

특수 문자 앞에 \를 추가하십시오.

s/\?page=one&/page\/one\//g

기타


답변

내가 개발중인 시스템에서 sed로 대체 될 문자열은 변수에 저장되어 sed로 전달되는 사용자의 입력 텍스트입니다.

이 게시물의 앞부분에서 언급했듯이 sed 명령 블록에 포함 된 문자열에 sed가 사용하는 실제 구분 기호가 포함되어 있으면 구문 오류로 인해 sed가 종료됩니다. 다음 예제를 고려하십시오.

이것은 작동합니다 :

$ VALUE=12345
$ echo "MyVar=%DEF_VALUE%" | sed -e s/%DEF_VALUE%/${VALUE}/g
MyVar=12345

이 휴식 :

$ VALUE=12345/6
$ echo "MyVar=%DEF_VALUE%" | sed -e s/%DEF_VALUE%/${VALUE}/g
sed: -e expression #1, char 21: unknown option to `s'

기본 구분 기호를 바꾸는 것은 sed가 구분 기호로 사용하는 특정 문자 (예 : “/”)를 사용자가 입력하는 것을 제한하고 싶지 않기 때문에 강력한 해결책이 아닙니다.

그러나 입력 문자열에서 구분 기호를 이스케이프 처리하면 문제가 해결됩니다. sed로 구문 분석하기 전에 입력 문자열에서 구분 문자를 체계적으로 이스케이프하는 아래 솔루션을 고려하십시오. 이러한 이스케이프는 sed 자체를 사용하여 대체로 구현할 수 있습니다.이 대체는 입력 문자열에 구분자가 포함되어 있어도 안전합니다. 입력 문자열이 sed 명령 블록의 일부가 아니기 때문입니다.

$ VALUE=$(echo ${VALUE} | sed -e "s#/#\\\/#g")
$ echo "MyVar=%DEF_VALUE%" | sed -e s/%DEF_VALUE%/${VALUE}/g
MyVar=12345/6

나는 이것을 다양한 스크립트가 사용할 함수로 변환했다 :

escapeForwardSlashes() {

     # Validate parameters
     if [ -z "$1" ]
     then
             echo -e "Error - no parameter specified!"
             return 1
     fi

     # Perform replacement
     echo ${1} | sed -e "s#/#\\\/#g"
     return 0
}


답변

이 줄은 세 가지 예에서 작동합니다.

sed -r 's#\?(page)=([^&]*)&#/\1/\2#g' a.txt
  • 나는 -r탈출을 구하는 데 사용 했습니다.
  • 선은 당신의 하나, 두 세 경우에 일반적이어야합니다. 당신은 하위 3 번을 할 필요가 없습니다

예를 들어 테스트하십시오 (a.txt) :

kent$  echo "?page=one&
?page=two&
?page=three&"|sed -r 's#\?(page)=([^&]*)&#/\1/\2#g'
/page/one
/page/two
/page/three


답변

replace.txt 해야한다

s/?page=/\/page\//g
s/&//g