sh 스크립트에서 sed를 사용할 때 어떤 문자를 이스케이프해야 합니까?

sh 스크립트에서 sed를 사용할 때 어떤 문자를 이스케이프해야 합니까?

다음 스크립트를 사용하세요.

#!/bin/sh
sed 's/(127\.0\.1\.1)\s/\1/' [some file]

sh( 여기)에서 실행 하려고 하면 dash이스케이프해야 하는 대괄호 때문에 실패합니다. 하지만 나는아니요백슬래시 자체는 이스케이프되어야 합니다(옥텟 사이 또는 \s또는 에서 \1). 여기에는 어떤 규칙이 있나요? 또는 을 사용해야 할 때는 {...}어떻게 해야 합니까 [...]? 도망가는 대신 해야 할 일의 목록이 있나요?

답변1

여기에는 shell과 sed라는 두 가지 수준의 설명이 있습니다.

셸에서는 작은따옴표 자체를 제외하고 작은따옴표 사이의 모든 내용이 문자 그대로 해석됩니다. 작은따옴표 사이에 작은따옴표를 작성하여 효과적으로 추가 할 수 있습니다 '\''(닫는 작은따옴표, 리터럴 작은따옴표, 열린 작은따옴표).

Sed가 사용하는 것기본 정규식. BRE에서는 문자 집합( ) 내를 제외하고 $.*[\^문자 그대로 처리하기 위해 문자 앞에 백슬래시를 붙여 인용해야 합니다 . […]문자, 숫자는 (){}+?|인용하면 안 됩니다. 일부 구현에서는 그 중 일부를 인용할 수 있습니다. 시퀀스 \(, \), \n및 일부 구현에서는 \{, \}, 및 기타 백슬래시+영숫자 문자는 특별한 의미를 갖습니다 \+. 일부 구현에서는 특정 위치에서 인용을 해제할 수 있습니다.\?\|$^

/또한 대괄호 표현식 외부의 정규 표현식에 표시하려면 앞에 백슬래시를 추가해야 합니다. 예 s~/dir~/replacement~를 들어 ;을 작성하여 대체 문자를 구분 기호로 선택할 수 있습니다. \~/dir~pBRE에 포함하려면 구분 기호 앞에 백슬래시가 있어야 합니다. BRE에서 특별한 의미가 있는 문자를 선택하고 문자 그대로 포함하려는 경우 세 개의 백슬래시가 필요합니다. 일부 구현에서는 다르게 동작할 수 있으므로 권장하지 않습니다.

즉, 다음과 같습니다 sed 's/…/…/'.

  • 작은따옴표 사이에 정규식을 작성합니다.
  • '\''작은따옴표로 정규식을 끝내는 데 사용됩니다 .
  • 백슬래시를 이러한 문자 앞에 추가하고 해당 문자 앞에만 추가합니다 $.*/[\]^(대괄호 표현식 내부에는 추가하지 않음). (기술적으로 앞의 백슬래시를 추가하면 안 되지만 ], 대괄호 표현식 외부에서 합계를 다르게 처리하는 구현을 본 적이 없습니다 ].)\]
  • 대괄호 표현식 내에서 문자 그대로 처리하려면 첫 번째 또는 마지막( 또는 , 아님 ) -인지 확인하세요 .[abc-][-abc][a-bc]
  • 대괄호 표현식 내에서 ^문자 그대로 처리하려면 다음과 같아야 합니다.아니요첫째(사용하려면 [abc^], 사용하지 않음 [^abc]).
  • ]대괄호 표현식과 일치하는 문자 목록에 포함하려면 해당 문자를 첫 번째 문자(또는 ^부정 세트의 경우 첫 번째 문자)로 만듭니다. []abc]또는 [^]abc]( [abc]]또는[abc\]] 아님 ).

대체 텍스트에서:

  • &구분 기호(보통 ) 및 개행 문자 \처럼 앞에 백슬래시를 붙여 인용해야 합니다 ./
  • \다음 숫자에는 특별한 의미가 있습니다. \뒤에 오는 문자는 일부 구현에서 특별한 의미(특수 문자)를 가지며, \다른 문자가 뒤에 오는 내용은 구현에 따라 달라지거나 \c의미 됩니다.c
  • 대체 텍스트에 작은따옴표를 추가 sed 's/…/…/'하려면 인수( )를 작은따옴표로 묶습니다 .'\''

정규식이나 대체 텍스트가 쉘 변수에서 나온 경우 다음을 기억하세요.

  • 정규식은 리터럴 문자열이 아닌 BRE입니다.
  • 정규식에서 개행은 다음과 같이 표현되어야 합니다(패턴 공간에 개행을 추가하는 다른 코드가 없으면 \n절대 일치하지 않습니다). sed그러나 일부 구현에서는 대괄호 표현식 내에서 작동하지 않습니다 sed.
  • 대체 텍스트에서는 , &\개행 문자를 인용해야 합니다.
  • 구분 기호는 따옴표로 묶어야 합니다(대괄호 표현식 안에는 포함되지 않음).
  • 보간에는 큰따옴표를 사용하십시오: sed -e "s/$BRE/$REPL/".

답변2

발생한 문제는 쉘 보간 및 이스케이프 때문이 아닙니다. sed -r또는 --regexp-extended옵션을 전달하지 않고 확장 정규식 구문을 사용하려고 하기 때문입니다.

sed 라인을 변경해 보세요

sed 's/(127\.0\.1\.1)\s/\1/' [some file]

도착하다

sed -r 's/(127\.0\.1\.1)\s/\1/' [some file]

의도하신대로 잘 되리라 확신합니다.

기본적으로 sed는 다음 구문이 필요한 기본 정규식(grep 스타일 생각)을 사용합니다.

sed 's/\(127\.0\.1\.1\)[ \t]/\1/' [some file]

답변3

sed 표현식에 쉘 변수를 삽입하려는 경우가 아니면 전체 표현식에 작은따옴표를 사용하십시오. 그러면 백슬래시를 포함하여 그 사이의 모든 내용이 있는 그대로 해석됩니다.

따라서 sed가 이를 볼 수 있도록 하려면 s/\(127\.0\.1\.1\)\s/\1/주위에 작은따옴표를 넣으십시오. 그러면 쉘이 괄호나 백슬래시를 건드리지 않습니다. 쉘 변수를 삽입해야 하는 경우 해당 부분을 큰따옴표로 묶으면 됩니다. 예를 들어

sed 's/\(127\.0\.1\.1\)/'"$ip"'/'

이렇게 하면 큰따옴표로 이스케이프되지 않은 쉘 메타 문자를 기억하는 수고를 덜 수 있습니다.

답변4

sed는 기본 정규 표현식(BRE)만 지원하도록 지정하는 POSIX 표준을 기반으로 하지만 실제로 sed 명령에는 BSD(Mac OS)와 GNU(Linux 배포판)라는 두 가지 다른 버전이 있다는 점을 언급할 가치가 있다고 생각합니다. . 각 버전은 유사하지만 고유한 POSIX 표준 확장 기능을 구현하며 다양한 플랫폼에서 sed의 기능에 영향을 미칠 수 있습니다. 따라서 한 시스템에서 예상대로 작동하는 sed 명령의 올바른 구문이 실제로 다른 시스템에서는 완전히 다른 결과로 해석될 수 있습니다. 이로 인해 이스케이프 및 특수 문자 사용과 관련하여 예기치 않은 동작이 발생할 수 있습니다.

POSIX 표준에 대한 이러한 확장은 sed의 GNU 버전에서 더 일반적인 경향이 있으며, 특히 BSD 버전에 비해 덜 엄격한 형식 지정 편의성을 제공하는 경우가 많습니다. 그러나 GNU sed는 일부 특수 문자 기능을 허용하지만 실제로는 POSIX와 호환되지 않습니다. 또한 GNU sed의 기본 정규식과 확장 정규식(ERE) 간의 유일한 실제 차이점은 다음 특수 문자의 동작입니다.

'?', '+', 괄호, 중괄호('{}') 및 '|'

그럴 수도 있지만 "|", "?" 및 "+"와 같은 일부 특수 문자는 POSIX 구문 표준을 더 엄격하게 준수하기 때문에 BSD sed에서 지원이 제한되거나 지원되지 않습니다. GNU sed와 유사한 방식으로 이러한 문자를 포함하면 sed를 사용하는 스크립트에 이식성 및 기능 문제가 발생하는 경우가 많습니다. POSIX BRE 구문은 특히 \|, +, \?, `, \', \<, >, \b, \B, \w 및 \와 같은 특정 이스케이프 시퀀스의 의미를 정의하지 않는다는 점도 주목할 가치가 있습니다. 와트,.

BSD/Mac OS 버전의 sed를 실행하는 경우 특정 특수 문자의 동작을 시뮬레이션하는 것이 약간 까다로울 수 있지만 대부분의 경우 완료할 수 있습니다. 예를 들어, +는 다음과 같이 POSIX 호환 방식으로 에뮬레이션될 수 있습니다. {1,} 및 \?는 다음과 같습니다. {0,1} 그러나 제어 문자 시퀀스는 일반적으로 지원되지 않습니다. 물론 가능하다면 GNU sed를 사용하는 것이 가장 쉽지만 두 플랫폼 모두에서 기능이 필요한 경우 이식성을 보장하기 위해 POSIX 기능만 사용해야 한다는 점을 기억하세요. Mac 사용자이고 BSD sed 대신 GNU sed를 활용하고 싶다면 Homebrew를 설치하고 $brew install gnu-sed 명령줄을 통해 GNU sed를 다운로드할 수 있습니다.

전체적으로 버전의 차이에 따라 올바른 구문이 어떤 것인지 또는 어떤 문자를 이스케이프해야 하는지가 실제로 결정될 수 있습니다. 이것이 원래 질문과 승인된 답변에 대한 추가 컨텍스트를 제공하고 다른 사람들이 스크립트 및 명령 사용에 대한 최종 목표에 따라 진행하는 방법을 생각하는 데 도움이 되기를 바랍니다.

관련 정보