변수를 사용하여 쉘 스크립트의 문자열 바꾸기


94

쉘 스크립트 내부의 문자열을 대체하기 위해 아래 코드를 사용하고 있습니다.

echo $LINE | sed -e 's/12345678/"$replace"/g'

하지만 $replace그 변수의 값 대신에 대체되고 있습니다.

아무도 무엇이 잘못되었는지 말할 수 있습니까?


슬래시가있는 값 처리에 대한 일반적인 관련 질문은 stackoverflow.com/questions/5864146/use-slashes-in-sed-replace
tripleee

답변:


147

해석하려는 경우 $replace작은 따옴표는 변수 대체를 방지하므로 사용하지 않아야합니다.

시험:

echo $LINE | sed -e "s/12345678/\"${replace}\"/g"

당신이 따옴표에 넣어 원하는 가정이있는 경우. 하지 않는 , 사용을 인용합니다 :

echo $LINE | sed -e "s/12345678/${replace}/g"

성적 증명서:

pax> export replace=987654321
pax> echo X123456789X | sed "s/123456789/${replace}/"
X987654321X
pax> _

이스케이프하지 않는 한 혼동을 일으킬 수 있으므로 (예 를 들어) ${replace}중요한 문자가 없는지 확인하십시오 . 그러나 말했듯이 한 번호를 다른 번호로 바꾸는 경우 문제가되지 않습니다.sed/


나는 따옴표가 들어와 하나 개의 번호가 서로 대체 할 넣어 싶지 않는
비제이

1
paxdiablo : set또한 필요하지 않습니다 (어쨌든 어떻게 사용하려고 했습니까?). 그냥 replace=987654321.
Roman Cheplyaka

나는 보통 export아이들을 위해 변수가 설정되도록 항상 사용 하지만, 당신이 말했듯이 쉽게 피할 수 있습니다. 그러나의 사용 여부 export는 여기서 (스타일 문제)와 관련이 없으며 sed명령 내에서 변수를 사용하는 방법 인 실제 답변에는 영향을 미치지 않습니다 .
paxdiablo

이 솔루션은 -i옵션 으로 작동하지 않는 것 같습니다 . 이유를 아십니까? 또는 작동하게하는 방법?
가브리엘

1
어쩌면 큰 따옴표로 단일로 전환하는 어떤 필요하다는 지적 $또는 `에서 sed스크립트를 두 번 인용 된 문자열을 쉘의 대체 메커니즘로부터 보호하기 위해, 백 슬래시로 이스케이프 할 수 있습니다.
tripleee

74

쉘 (bash / ksh)을 사용할 수 있습니다.

$ var="12345678abc"
$ replace="test"
$ echo ${var//12345678/$replace}
testabc

3
그것이 bash 특정 (및 ksh?)임을 언급하고 싶을 수 있습니다. 아마 대부분의 사람들에게 수입하지만 우리 중 일부의 여전히 :-) 고대 UNIXen에 대한 작업을 강제하지
paxdiablo

6
주의하십시오. 이것은 /bin/sh많은 최신 Linux 에있는 dash에서도 실패합니다 .
phihag

27

질문에 국한되지 않지만 이전 답변에서 명확성을 위해 확장 된 동일한 종류의 기능이 필요한 사람들을 위해 :

# create some variables
str="someFileName.foo"
find=".foo"
replace=".bar"
# notice the the str isn't prefixed with $
#    this is just how this feature works :/
result=${str//$find/$replace}
echo $result    
# result is: someFileName.bar

str="someFileName.sally"
find=".foo"
replace=".bar"
result=${str//$find/$replace}
echo $result    
# result is: someFileName.sally because ".foo" was not found


8

작은 따옴표는 매우 강력합니다. 일단 안으로 들어가면 떠날 때까지 변수 대체를 호출하기 위해 할 수있는 일이 없습니다. 대신 큰 따옴표를 사용하십시오.

echo $LINE | sed -e "s/12345678/$replace/g"

4
echo $LINE | sed -e 's/12345678/'$replace'/g'

여전히 작은 따옴표를 사용할 수 있지만 올바른 위치에서 변수를 확장하려면 "열어야"합니다. 그렇지 않으면 문자열이 "문자 그대로"사용됩니다 (@paxdiablo가 올바르게 언급했듯이 그의 대답도 정확합니다)


$replace따옴표 외부 를 사용 하면 쉘이 값에 대해 공백 토큰 화 및 와일드 카드 확장을 수행하게 되는 문제 가 있습니다. 이것은 단순한 값으로 작동하는 것처럼 보이지만 사소하지 않은 문자열에서는 극적으로 폭발 할 수 있습니다. 프로덕션 코드에서 이것을 사용하지 마십시오.
tripleee

2

쉘이 변수를 확장하게하려면 다음과 같은 큰 따옴표를 사용해야합니다.

sed -i "s#12345678#$replace#g" file.txt

$replace특수 sed문자 ( #, \) 가 포함 된 경우 중단됩니다 . 그러나 $replace이를 인용하기 위해 사전 처리 할 수 있습니다.

replace_quoted=$(printf '%s' "$replace" | sed 's/[#\]/\\\0/g')
sed -i "s#12345678#$replace_quoted#g" file.txt

0

비슷한 요구 사항이 있었지만 교체 변수에 앰퍼샌드가 포함되어 있습니다. 이와 같은 앰퍼샌드를 이스케이프하면 내 문제가 해결되었습니다.

replace="salt & pepper"
echo "pass the salt" | sed "s/salt/${replace/&/\&}/g"

-1

대신 사용

echo $LINE | sed -e 's/12345678/$replace/g'

이것은 나를 위해 단순히 따옴표를 제거하십시오.


-2

나는 큰 따옴표를 사용하는 것을 선호한다. 단일 quptes는 그 안의 어떤 것도 변경할 수 없거나 변수 치환을 호출 할 수있는 경우에 사용한만큼 매우 강력하기 때문이다.

따라서 큰 따옴표를 사용하십시오.

echo $LINE | sed -e "s/12345678/$replace/g"

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