![sed 명령이 대화형으로 작동하지만 내 스크립트에서는 작동하지 않는 이유는 무엇입니까? [복사]](https://linux55.com/image/126048/sed%20%EB%AA%85%EB%A0%B9%EC%9D%B4%20%EB%8C%80%ED%99%94%ED%98%95%EC%9C%BC%EB%A1%9C%20%EC%9E%91%EB%8F%99%ED%95%98%EC%A7%80%EB%A7%8C%20%EB%82%B4%20%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8%EC%97%90%EC%84%9C%EB%8A%94%20%EC%9E%91%EB%8F%99%ED%95%98%EC%A7%80%20%EC%95%8A%EB%8A%94%20%EC%9D%B4%EC%9C%A0%EB%8A%94%20%EB%AC%B4%EC%97%87%EC%9E%85%EB%8B%88%EA%B9%8C%3F%20%5B%EB%B3%B5%EC%82%AC%5D.png)
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