저는 Linux에 상대적으로 초보자입니다. a.txt
다음 텍스트가 포함된 텍스트 파일이 있다고 가정해 보겠습니다 .
A
B
C
이제 2행(포함)의 텍스트를 변경하려면 B
다음 sed
명령을 사용할 수 있습니다.
sed -i '2s/^.*$/X/' a.txt
예를 들어 B
로 변경합니다 .X
sed
하지만 이제 2번째 줄의 텍스트를 다음으로 변경하는 명령을 작성하고 싶다고 가정해 보겠습니다.포함하다bash 문자열 변수. 2번째 줄의 텍스트를 fname="myaddress"
따옴표가 명시적으로 포함된 myaddress
로 변경하고 싶습니다 .bash 문자열 변수(다른 곳에서 정의됨) 이를 시도하기 위해 mytest.sh
다음 내용을 포함하는 bash 쉘 스크립트를 만들었습니다.
#!/bin/bash
myaddress="/home/"
echo fname=\"$myaddress\"
head a.txt
sed -i '2s/^.*$/fname=\"$myaddress\"/' a.txt
head a.txt
이제 echo fname=\"$myaddress\"
인쇄하세요 fname="/home/"
. 이것이 내 텍스트입니다.생각하다2호선에 위치 a.txt
. 그러나 sed
대신 fname="$myaddress"
2번째 줄에 인쇄합니다 a.txt
. 아마도 주변 아포스트로피 안에 있기 때문일 것입니다. 즉, 위 bash 쉘 스크립트의 출력은 다음과 같습니다.
fname="/home/"
A
B
C
A
fname="$myaddress"
C
내 질문은 sed
실제로 어떻게 인쇄 할 수 있는지입니다.값?에 저장되고 myaddress
? $myaddress
에서 참조됨
답변1
s
변수의 내용에 관계없이 대체가 작동하도록 하려면 다음을 sed
포함하여 변수의 명령 오른쪽에 있는 특수 문자를 이스케이프해야 합니다.
- 구분 기호 자체(위에서 사용함
/
) &
일치하는 문자열로 대체됨- 이스케이프해야 할 줄바꿈
\
위의 모든 내용을 벗어나서 , ...을 소개하는 데 사용됩니다\1
.\2
좋다:
escaped_var=$(printf '%s\n' "$var" | sed 's:[/&\]:\\&:g;s/$/\\/')
escaped_var=${escaped_var%?}
sed "s/regexp/$escaped_var/g"
이는 매우 번거롭기 때문에 다음을 사용하는 것이 좋습니다 perl
.
v=$var perl -pe 's/regexp/$ENV{v}/g'
sed
다음과 같습니다 2s
.
v=$var perl -pe 's/regexp/$ENV{v}/g if $. == 2'
물론 귀하의 경우 다음과 같이 작성하는 것이 좋습니다.
v=$myaddress perl -pe '$_ = "fname=\"$ENV{v}\"\n" if $. == 2'
또 다른 장점은 바이너리 데이터도 처리할 수 있고 GNU 기반 시스템에서만 수행 할 수 -i
있는 내부 편집 옵션이 있다는 것입니다 .sed
sed
sed
또한 NUL 문자는 환경 변수에 저장할 수 없습니다.
답변2
쉘은 작은따옴표 안의 변수를 해석하지 않습니다. 큰따옴표로 변경해야 합니다. 변수에 슬래시가 있으므로 다른 구분 기호를 사용해야 합니다.
sed -i "2s|^.*\$|fname=\"$myaddress\"|" a.txt
$
쉘이 그것을 해석하지 못하도록 줄 끝을 이스케이프 처리했다는 점에 유의하십시오 . 이 경우는 아니지만, $
유지하려는 s를 큰따옴표로 묶어 이스케이프 처리하는 습관을 들여야 합니다 . 이 작업을 수행하려면 몇 쌍의 따옴표를 사용할 수도 있습니다.
sed -i '2s|^.*$|fname="'"$myaddress"'"|' a.txt
답변3
두 가지 문제가 있습니다. 첫째, Kevin이 이미 지적한 것처럼 쉘 변수를 쉘에 의해 확장하려면 해당 변수를 큰따옴표로 묶어야 합니다. 둘째, 대체 문자열에 가 포함되어 있으므로 이를 구분 기호로 사용할 /
수도 없습니다 . 특정 문자(예: )가 대체 문자열에 확실히 나타나지 않는다는 것을 알고 있는 경우 해당 문자를 구분 기호로 사용하여 다음을 얻을 수 있습니다./
sed
,
sed
sed -i '2s,^.*$,fname="'"$myaddress"'",' a.txt