Programing

sed에서 환경 변수 대체

crosscheck 2020. 5. 31. 10:04
반응형

sed에서 환경 변수 대체


스크립트에서 이러한 명령을 실행하면

#my.sh
PWD=bla
sed 's/xxx/'$PWD'/'
...
$ ./my.sh
xxx
bla

그것은 괜찮습니다.

그러나 내가 달리면 :

#my.sh
sed 's/xxx/'$PWD'/'
...
$ ./my.sh
$ sed: -e expression #1, char 8: Unknown option to `s' 

튜토리얼에서 쉘에서 환경 변수를 대체하고 중지 해야하는 $varname부분을 인용하여 직접 대체하지 않도록 부품을 인용 합니다. 이것은 내가 한 일이며 변수가 바로 정의 된 경우에만 작동합니다.

$var쉘에 정의 된 환경 변수로 sed를 어떻게 인식 할 수 있습니까?


두 예제가 동일 해 보이므로 문제를 진단하기가 어렵습니다. 잠재적 인 문제 :

  1. 다음과 같이 큰 따옴표가 필요할 수 있습니다. sed 's/xxx/'"$PWD"'/'

  2. $PWD슬래시를 포함 할 수 있으며,이 경우 구분자로 사용하기 위해 포함 되지 않은 문자를 찾아야합니다 $PWD.

한 번에 두 문제를 모두 해결하려면

sed 's@xxx@'"$PWD"'@'

Norman Ramsey의 답변 외에도 전체 문자열을 큰 따옴표로 묶을 수 있습니다 (문을 더 읽기 쉽고 오류가 덜 발생 할 수 있음).

따라서 'foo'를 검색하여 $ BAR의 내용으로 바꾸려면 sed 명령을 큰 따옴표로 묶을 수 있습니다.

sed 's/foo/$BAR/g'
sed "s/foo/$BAR/g"

첫 번째, $ BAR은 올바르게 확장되지 않지만 두 번째 $ BAR은 올바르게 확장됩니다.


"/"이외의 다른 문자를 대신 사용할 수 있습니다.

sed "s#$1#$2#g" -i FILE

또 다른 쉬운 대안 :

때문에 $PWD일반적으로 슬래시를 포함 /, 사용 |대신 /나오지 문 :

sed -e "s|xxx|$PWD|"

질문을 편집하면 문제가 발생합니다. 현재 디렉토리가 /home/yourname...이 경우 아래 명령 이라고 가정 해 봅시다 .

sed 's/xxx/'$PWD'/'

로 확장됩니다

sed `s/xxx//home/yourname//

유효하지 않습니다. 이렇게하려면 $ PWD에서 \각 문자 앞에 문자 를 넣어야합니다 /.


나쁜 방법 : 구분 기호 변경

sed 's/xxx/'"$PWD"'/'
sed 's:xxx:'"$PWD"':'
sed 's@xxx@'"$PWD"'@'

아마 최종 답변이 아닌 사람들은

$PWD, / :OR 에서 어떤 캐릭터가 나타날지 알 수 없습니다 @.

좋은 방법은의 특수 문자를 바꾸는 것입니다 $PWD.

좋은 방법 : 탈출 구분 기호

예를 들면 다음과 같습니다.

/구분자로 사용

echo ${url//\//\\/}
x.com:80\/aa\/bb\/aa.js

echo ${url//\//\/}
x.com:80/aa/bb/aa.js

echo "${url//\//\/}"
x.com:80\/aa\/bb\/aa.js

echo $tmp | sed "s/URL/${url//\//\\/}/"
<a href="x.com:80/aa/bb/aa.js">URL</a>

echo $tmp | sed "s/URL/${url//\//\/}/"
<a href="x.com:80/aa/bb/aa.js">URL</a>

또는

:구분 기호로 사용 (보다 읽기 쉬운 /)

echo ${url//:/\:}
x.com:80/aa/bb/aa.js

echo "${url//:/\:}"
x.com\:80/aa/bb/aa.js

echo $tmp | sed "s:URL:${url//:/\:}:g"
<a href="x.com:80/aa/bb/aa.js">x.com:80/aa/bb/aa.js</a>

Actually, the simplest thing (in gnu sed at least) is to use a different separator for the sed substitution (s) command. So instead of s/pattern/'$mypath'/ being expanded to s/pattern//my/path/ which will of course confuse the s command, use s!pattern!'$mypath'! which will be expanded to s!pattern!/my/path! I've used the bang (!) character (or use anything you like) which avoids the usual, but-by-no-means-your-only-choice forward slash as the separator.


VAR=8675309
echo "abcde:jhdfj$jhbsfiy/.hghi$jh:12345:dgve::" |\
sed 's/:[0-9]*:/:'$VAR':/1' 

where VAR contains what you want to replace the field with


Dealing with VARIABLES within sed

[root@gislab00207 ldom]# echo domainname: None > /tmp/1.txt

[root@gislab00207 ldom]# cat /tmp/1.txt

domainname: None

[root@gislab00207 ldom]# echo ${DOMAIN_NAME}

dcsw-79-98vm.us.oracle.com

[root@gislab00207 ldom]# cat /tmp/1.txt | sed -e 's/domainname: None/domainname: ${DOMAIN_NAME}/g'

 --- Below is the result -- very funny.

domainname: ${DOMAIN_NAME}

 --- You need to single quote your variable like this ... 

[root@gislab00207 ldom]# cat /tmp/1.txt | sed -e 's/domainname: None/domainname: '${DOMAIN_NAME}'/g'


--- The right result is below 

domainname: dcsw-79-98vm.us.oracle.com

I had similar problem, I had a list and I have to build a SQL script based on template (that contained @INPUT@ as element to replace):

for i in LIST 
do
    awk "sub(/\@INPUT\@/,\"${i}\");" template.sql >> output
done

참고URL : https://stackoverflow.com/questions/584894/environment-variable-substitution-in-sed

반응형