sed 명령이 대화형으로 작동하지만 내 스크립트에서는 작동하지 않는 이유는 무엇입니까? [복사]

sed 명령이 대화형으로 작동하지만 내 스크립트에서는 작동하지 않는 이유는 무엇입니까? [복사]

SED 명령은 Debian의 bash를 대체하지 않지만 명령줄에서 사용할 수 있습니다.

명령줄에서 작업:

sed -i 's|/dev/disk/by-label/SR6D4|/dev/disk/by-label/SR4D4|g' /etc/my/config.xml

Bash 스크립트에서는 작동하지 않으며 문자열을 대체하지 않습니다.

from="SR6D4"
to="SR4D4"
path_from="/dev/disk/by-label/${from}"
path_to="/dev/disk/by-label/${to}"
echo "sed -i 's|${path_from}|${path_to}|g' $file"
sed -i 's|${path_from}|${path_to}|g' $file

Bash에서 sed를 사용할 때 파일의 문자열이 대체되지 않는 이유는 무엇입니까?

답변1

쉘 변수는 작은따옴표 내에서 확장되지 않습니다. (이것은 작은 따옴표의 용도와 비슷합니다.)

sed -i "s|${path_from}|${path_to}|g" "$file"

더 잘 작동해야합니다. ( $file파일 이름에 공백이 포함되어 있는 경우를 대비해 큰따옴표를 추가했습니다 .)

답변2

언급했듯이 인용에 문제가 있습니다. 그러나 파일의 문자열 교체에 대해서는 몇 가지 의견이 있습니다. 아래를 참조하세요.

파일의 문자열을 바꾸는 것은 안전하지 않기 때문에 좋지 않은 생각입니다. 변경 시 파일 데이터가 손실될 가능성이 적습니다.

변경하기 전에 파일을 백업해 볼 수 있습니다.

cp /path/to/file{,.backup}
sed -i 'place your pattern here' /path/to/file

라는 파일을 받게 됩니다 file.backup.

기억해야 할 점: 파일이 손상되어 파일을 삭제하고 교체하는 경우 파일은 다른 inode를 갖게 되며 모든 하드 링크는 손실됩니다.

두 번째 보안 방법:

mv /path/to/file{,.backup}; 
cat /path/to/file.backup | sed 'place your pattern here' > /path/to/file

다음 포인트. ~처럼bash 자주 묻는 질문은 생각합니다:

sed 명령에 쉘 변수를 포함시키는 것은 결코 좋은 생각이 아닙니다.

awk그렇기 때문에 options 을 사용해야 합니다 -v. 스크립트는 다음과 같습니다.

from="SR6D4"
to="SR4D4"
path_from="/dev/disk/by-label/${from}"
path_to="/dev/disk/by-label/${to}"
sed -i 's|${path_from}|${path_to}|g' $file
mv $file{,.backup}
cat "${file}.backup" | awk -v awkfrom="$path_from" -v awkto="$path_to" '{gsub(awkfrom,awkto)}' > $file

관련 정보