sed가 대체 문자열을 해석하지 못하도록 하는 방법이 있나요?

sed가 대체 문자열을 해석하지 못하도록 하는 방법이 있나요?

sed문자열 대체 키워드를 사용하려면 sed대체 문자열을 해석하도록 노력하세요. 대체 문자열에 sed특수한 것으로 간주되는 문자(예: char)가 포함된 경우, 무엇을 해야 할지 알려주는 문자가 /대체 문자열에 포함되기를 원하지 않는 한 실패합니다 .sed

전임자:

VAR="hi/"

sed "s/KEYWORD/$VAR/g" somefile

sed특수 문자를 해석하지 않도록 대체 문자열을 지시하는 방법이 있습니까 ? 내가 원하는 것은 내용이 무엇이든 상관없이 파일의 키워드를 변수의 내용으로 바꿀 수 있는 것입니다.

답변1

교체 부분에는 특수 문자 4개만 있습니다: \, &, 개행 문자 및 구분 기호(인용하다)

$ VAR='abc/def&ghi\foo
next line'

$ repl=$(sed -e 's/[&\\/]/\\&/g; s/$/\\/' -e '$s/\\$//' <<<"$VAR")

$ echo "$repl"
abc\/def\&ghi\\foo\
next line

$ echo ZYX | sed "s/Y/$repl/g"
Zabc/def&ghi\foo
next lineX

답변2

-psed (루핑 입력 가정) 및 -e(명령줄에 프로그램 제공) 대신 Perl을 사용할 수 있습니다 . Perl을 사용하면 환경 변수에 액세스할 수 있습니다.아니요이것을 쉘에 삽입하십시오. 이 변수는 다음과 같아야 합니다.출구:

export VAR='hi/'
perl -p -e 's/KEYWORD/$ENV{VAR}/g' somefile

변수를 어디로도 내보내지 않으려면 프로세스에 제공하면 됩니다.

PATTERN="$VAR" perl -p -e 's/KEYWORD/$ENV{PATTERN}/g' somefile

Perl의 정규식 구문은 기본적으로 sed의 구문과 약간 다릅니다.

답변3

대부분의 변수 값을 올바르게 처리하는 가장 간단한 솔루션은 인쇄되지 않는 문자를 sed대체 명령의 구분 기호로 사용하는 것입니다.

vi많은 쉘 에서는 ^VCtrl-V(보통 로 작성됨)를 입력하여 모든 제어 문자를 이스케이프할 수 있습니다. 따라서 일부 제어 문자( ^A이 경우 구분 기호로 자주 사용함) 를 사용하는 경우 sed해당 비인쇄 문자가 입력한 변수에 있는 경우에만 명령이 중단됩니다.

따라서 쉘 "s^V^AKEYWORD^V^A$VAR^V^Ag"에 입력하는 내용은 vi다음과 같습니다.

sed "s^AKEYWORD^A$VAR^Ag" somefile

(이 답변은 복사하여 붙여넣을 수 없습니다. 실제로 설명대로 입력해야 합니다.)

$VAR이는 인쇄할 수 없는 문자를 포함하지 않는 한 작동합니다 ^A. 그럴 가능성은 거의 없습니다.


물론 합격하면사용자 입력value $VAR이면 모든 베팅이 취소되고 일반 사용자가 입력하기 어려운 제어 문자에 의존하는 것보다 입력을 완전히 정리하는 것이 더 좋습니다.


그러나 실제로는 구분 기호 문자열보다 주목할 사항이 더 많습니다. 예를 들어 &대체 문자열에 나타나는 경우 "전체 텍스트가 일치합니다."를 의미합니다. 예를 들어, s/stu../my&/"stuff"를 "mystuff"로 바꾸고, "stung"을 "mystung"으로 바꾸세요. 그래서 만약 당신이어느문자를 대체 문자열로 변수에 넣고 싶지만 해당 변수의 리터럴 값만 사용하려는 경우 해당 변수를 에서 대체 문자열로 사용하기 전에 일부 데이터 정리를 수행해야 합니다 sed. (단, 데이터 클리닝도 가능합니다 sed.)

답변4

라인 기반이고 교체할 라인이 하나뿐인 경우 를 사용하여 파일 자체 앞에 교체 라인을 추가하고 printf첫 번째 라인을 sed예약된 공간에 저장한 후 필요에 따라 넣는 것이 좋습니다. 이렇게 하면 특수 문자에 대해 전혀 걱정할 필요가 없습니다. (여기서 유일한 가정은 $VAR줄 바꿈 없이 텍스트 줄을 포함하는 것인데, 이는 귀하의 의견에서 말한 것입니다.) 줄 바꿈 외에도 VAR에는 다음이 포함될 수 있습니다.아무것어쨌든 이것은 작동합니다.

VAR=whatever
{ printf '%s\n' "$VAR";cat somefile; } | sed '1{h;d;};/KEYWORD/g'

printf '%s\n'$VAR내용에 관계없이 리터럴 문자열로 인쇄되고 그 뒤에 개행 문자가 옵니다. ( echo경우에 따라 다른 작업이 수행됩니다. 예를 들어 의 내용이 $VAR하이픈으로 시작하면 에 전달된 옵션 플래그로 해석됩니다 echo.)

printf중괄호는 에 전달된 콘텐츠 의 출력 앞에 추가하는 데 사용됩니다 . 여기서는 닫는 중괄호 앞의 세미콜론과 마찬가지로 중괄호 자체를 구분하는 공간이 중요합니다.somefilesed

1{h;d;};명령 은 sed텍스트의 첫 번째 줄을 sed's' 에 저장합니다.예비 공간를 누른 다음 d해당 줄을 삭제합니다(인쇄하는 대신).

/KEYWORD/포함된 모든 행에 다음 작업을 적용합니다 KEYWORD. 작업은 get이며, 예약된 공간의 내용을 가져와서 다음으로 대체합니다.패턴 공간- 즉, 현재 행 전체입니다. (단순히 교체만을 위한 것이 아닙니다.부분그런데 예약된 공간은 지워지지 않고 그냥복사패턴 공간에 들어가서 그 안에 있는 모든 것을 바꿉니다.

네가 원한다면정규식이므로 일치하지 않습니다.포함하다KEYWORD인데 한 줄만 있고 KEYWORD 외에는 아무것도 없습니다. ^정규식에 첫 번째 줄 기준점( )과 끝 줄 기준점( )을 추가하세요.$

VAR=whatever
{ printf '%s\n' "$VAR";cat somefile; } | sed '1{h;d;};/^KEYWORD$/g'

관련 정보