[unix] sed 대체의 LHS 및 RHS에서 변수를 사용하려면 어떻게해야합니까?

나하고 싶어:

cat update_via_sed.sh | sed 's/old_name/new_name/' > new_update_via_sed.sh

내 프로그램에서.

그러나 나는 변수를 사용하고 싶다.

old_run='old_name_952'
new_run='old_name_953'

나는 그것들을 사용하려고 시도했지만 대체가 발생하지 않습니다 (오류 없음). 나는 시도했다 :

cat update_via_sed.sh | sed 's/old_run/new_run/'
cat update_via_sed.sh | sed 's/$old_run/$new_run/'
cat update_via_sed.sh | sed 's/${old_run}/${new_run}/'



답변

당신은 할 수 있습니다 :

sed "s/$old_run/$new_run/" < infile > outfile

하지만 조심 $old_run정규 표현식으로 간주 될 수와 같은 변수가 포함되어 있으므로 특수 문자, /또는 .해야 이스케이프 . 마찬가지로에서 $new_run&\문자는 특별하게 취급 될 필요가 당신은 탈출해야합니다 /거기에와 줄 바꿈 문자를.

의 내용이있는 경우 $old_run또는 $new_run당신의 통제하에 있지, 그것은 탈출 것을 수행하는 것이 중요합니다, 또는 그렇지 않으면 그 코드는 코드 주입 취약점에 달한다 .


답변

이것은 효과가 있었다 :

cat update_via_sed.sh | sed 's/'"$old_run"'/'"$new_run"'/'

동일한 파일을 ‘재사용’하기 위해 비슷한 접근 방식을 원하는 사람에게 실제로 이것을 사용합니다.

cat update_via_sed.sh | sed 's/'"$old_run"'/'"$new_run"'/' > new_update; mv -f new_update update_via_sed.sh

위의 새 파일을 만든 다음 새 파일의 이름을 현재 파일로 바꾸는 것보다 현재 파일을 삭제합니다.


답변

큰 따옴표 (작은 따옴표가 아님) 인 한 sed에서 변수를 사용할 수 있습니다.

sed "s/$var/r_str/g" file_name >new_file

/변수에 슬래시 ( ) 가 있으면 아래처럼 다른 구분 기호를 사용하십시오

sed "s|$var|r_str|g" file_name >new_file


답변

‘in-place’sed (-i 플래그 사용)가 답입니다. peterph에게 감사합니다.

sed -i "s@$old@$new@" file


답변

man bash 작은 따옴표에 대해 이것을 제공합니다

작은 따옴표로 문자를 묶으면 따옴표 안에 각 문자의 리터럴 값이 유지됩니다. 백 슬래시가 앞에 있어도 작은 따옴표 사이에는 작은 따옴표가 없을 수 있습니다.

bash는 명령 줄에 입력 한 내용을 해석하고 해석하여 결과를 전송 될 프로그램으로 보냅니다.이 경우 sed 's/$old_run/$new_run/'bash 를 사용하면을 먼저보고 변수에 sed실행 파일로 인식 $PATH. sed실행 파일은 입력이 필요합니다. 배시는 입력을 찾아서 찾습니다 's/$old_run/$new_run/'. 작은 따옴표는 bash가 내용을 해석하지 않고 그대로 전달하지 말라고 말합니다. 따라서 bash는 sed로 전달합니다. $줄 끝에서만 발생할 수 있으므로 Sed에서 오류 가 발생합니다.

대신 큰 따옴표, 즉 "s/$old_run/$new_run/"bash를 사용하면 bash는 이것을보고 $old_run변수 이름으로 해석 하고 대체합니다 (이 단계를 변수 확장이라고합니다). 이것이 실제로 우리가 요구 한 것입니다.

그러나 큰 따옴표는 bash에서 먼저 해석 한 다음 sed에 제공되므로주의해야합니다. 따라서`와 같은 일부 기호는 사용하기 전에 이스케이프해야합니다.


답변

플립 패인의 위험이 있습니다 perl.

무엇보다도 ‘sed style’작업을 수행하는 데 능숙하지만 더 완전한 기능을 갖춘 프로그래밍 기능입니다.

그것은 보이는 당신의 예처럼, 당신이있어 무엇을 실제로 일을하려고하는 숫자를 증가한다.

그래서 어떻습니까 :

#!/usr/bin/env perl
use strict;
use warnings 'all';

while ( <DATA> ) {
    s/old_name_(\d+)/"old_name_".($1+1)/e;
    print;
}

__DATA__
old_name_932

또는 하나의 라이너-sed 스타일로 :

perl -pe 's/old_name_(\d+)/"old_name_".($1+1)/e'


답변

$ echo $d1 | sed -i 's/zkserver1/'${d1}'/g' deva_file
sed: -e expression #1, char 26: unterminated `s' command

에서 $d1나는 값을 저장하고

변수의 값을 바꿀 수 없으므로 다음 명령을 시도했습니다.

echo $d1 | sed -i 's/zkserver1/'"${d1}"'/g' deva_file

에 큰 따옴표가 없습니다 "${d1}". 오류입니다.