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


147

로컬로 개발 된 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


답변:


274

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

s:?page=one&:pageone:g

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

s/\//foo/

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


1
> 또는 백 슬래시로 이스케이프 처리 할 수 ​​있습니다. 문자열의 어떤 문자가 다른 것을 선택할 수 있는지 항상 알지 못하기 때문에 그 예가 더 유용합니다. 예를 들면 다음과 같습니다. echo / | sed s / \ // a / g가 작동하지 않습니다 : sed : -e expression # 1, char 5 :`s '에 대한 알 수없는 옵션
Max Waterman

1
그런 다음 추가 할 수 있습니까? 감사합니다 :) 큰 따옴표로 둘러싼 주변 장치가 작동하는 것으로 나타났습니다. echo / | sed "s / \ // a / g"
Max Waterman

@MaxWaterman sed정규식 명령을 사용할 때 표준 작동 절차 는 큰 따옴표로 묶습니다. 전체 sed명령 줄을 표시하지 않았지만 sedOP가 수행 한 정규식 명령 문자열 만 표시했기 때문에 대답에 사용하지 않았습니다 . OP와 마찬가지로 파일에 넣으면 따옴표가 필요하지 않습니다.
lurker

예, 충분히 공정합니다 (아마도 언급 할 수 있음). 그 예가 도움이됩니다. 나는 때때로 많은 백 슬래시를 넣을 필요가 있다는 것을 알게되었습니다 ... 그리고 그것은 정말로 혼란스러워집니다. 예를 들어, -e "s / '/ \\\\\\\ & / g"텍스트가 잘못되었다고 생각합니다. "\는 foo로 바꿀 것"- "/는 foo로 바꿀 것"입니까?
Max Waterman

@MaxWaterman은 \ 대 /를 잡아 주셔서 감사합니다. 고쳤다. sed쉘 스크립트에 명령 이 있으면 더 많은 백 슬래시가 필요할 수 있습니다 (각 백 슬래시는 다시 백 슬래시되어야합니다).
lurker

105

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

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

5
OS X에있는 BSD의 매뉴얼 페이지는 s 명령을 말합니다 : 패턴 공간에서 정규 표현식의 첫 번째 인스턴스를 대체 문자열로 바꿉니다. 슬래시 대신 백 슬래시 또는 개행 문자 이외의 문자를 사용하여 RE와 대체 문자를 구분할 수 있습니다. GNU sed 매뉴얼 페이지에 비슷한 내용이 있다고 생각합니다.
Tom Anderson

현재 허용되는 답변은 기본적으로이 답변과 동일하며 1 분 전에 게시되었습니다!
Tom Anderson

61

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


슬래시를 대체하려는 경우 천재 조언. 감사!
mbb

9

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

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

기타


4
뭔가를 놓쳤을 수도 있지만 시도했지만 작동하지 않는 것 같습니다. 시도하는 것이 분명한 것처럼 보였지만 내가 옳고 실제로 작동하지 않는다고 가정하면 왜 게시해야합니까?
codenoob

4
@codenoob (그리고 여기에 오는 다른 사람들)-처음에는 's'가 필요합니다. s/foo\/bar/foo_bar/작동하지만 작동 /foo\/bar/foo_bar/하지 않습니다.
MynockSpit

5

내가 개발중인 시스템에서 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
}

1
귀하의 답변에서 벗어난 것은 DEF_VALUE를 대체하는 데 사용하는 VALUE에 슬래시가 있으면 sed가 작동하기 위해 3 개의 백 슬래시로 이스케이프 처리해야한다는 것입니다.VALUE="01\\\/01\\\/2018"
alexkb

3

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

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


1

익명의 큰 답변. \ HTML 문자열에서 따옴표를 이스케이프하려고 할 때 문제가 해결되었습니다.

따라서 sed를 사용하여 서버에서 일부 HTML 템플릿을 반환하는 경우 단일 대신 이중 백 슬래시를 사용하십시오.

var htmlTemplate = "<div style=\\"color:green;\\"></div>";

1

sedS tream 에드 당사 홈페이지에서 , 당신이 사용할 수에 |보내 (파이프) 표준 스트림 을 통해 (STDIN과 STDOUT 특별히을) sed과 유닉스 철학의 전통에 편리한 도구 만들기, 즉석에서 프로그램을 변경하는 행위 -i아래 언급 된 매개 변수를 사용하여 파일을 직접 편집 할 수도 있습니다.
다음을 고려하십시오 .

sed -i -e 's/few/asd/g' hello.txt

s/에 사용되는 발견 표현 ubstitute few과를 asd:

용감한 소수.


바보, 용감한.

/g"전역 (global)"을 의미하며, 전체 라인에서이를 수행한다는 의미입니다. 를 사용하지 않고 /g(와 함께 s/few/asd/항상 3 개의 슬래시가 있어야 함) few같은 줄에 두 번 나타나는 경우 첫 번째 만 다음 few으로 변경됩니다 asd.

소수의 남자, 소수의 여자, 용감한.


엉덩이 남자, 몇 여자, 용감한.

이것은 줄의 시작 부분에 특수 문자를 변경하는 것과 같은 일부 상황에서 유용합니다 (예를 들어, 일부 사람들이 이메일 스레드에서 이전 자료를 가로 탭으로 인용하는 데 사용되는 것보다 큰 기호를 대체하면서 인용 된 대수 부등식은 나중에 줄에 표시 함) 손길이 닿지 않는 곳), 예를 들어 어디서나 few 발생하도록 지정하는 경우 교체해야합니다 /g.

다음 두 옵션 (플래그)이 하나로 결합됩니다. -ie .

-i옵션은 편집에 사용되는 난의 파일에 n 개의 장소hello.txt .

-e옵션은 실행할 e- expression / 명령을 나타냅니다.s/ .

참고 : -i -e검색 / 바꾸는 데 사용 하는 것이 중요합니다 . 이 경우 -ie문자 'e'가 추가 된 모든 파일의 백업을 만듭니다.


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.