这篇文章以sed的一个参数的使用示例进行说明在不同操作系统之下,一些常用的命令或者操作系统内置的功能可能会有所不同,是脚本编程在实际编码中需要额外注意的事情。
比如希望把如下文本文件中的GREETING_MSG使用sed替换成liu miao
[root@liumiaocn ~]# cat test.text hello GREETING_MSG to use bash [root@liumiaocn ~]#示例代码
[root@liumiaocn ~]# cat test.sh #!/bin/bash FILE_TXT=test.text WORDS_REPLACE_SRC="GREETING_MSG" WORDS_REPLACE_DST="liu miao" if [ ! -f ${FILE_TXT} ]; then echo "File $FILE_TXT does not exist" exit 1 fi echo "Before sed -i " cat $FILE_TXT echo sed -i s@"${WORDS_REPLACE_SRC}"@"${WORDS_REPLACE_DST}"@g $FILE_TXT echo "After sed -i " cat $FILE_TXT [root@liumiaocn ~]#CentOS 7.7下的执行结果
[root@liumiaocn ~]# cat /etc/redhat-release CentOS Linux release 7.7.1908 (Core) [root@liumiaocn ~]# sh test.sh Before sed -i hello GREETING_MSG to use bash After sed -i hello liu miao to use bash [root@liumiaocn ~]#macOS下的执行结果
同样的代码和准备在macOS下的执行结果如下所示:
liumiaocn:~ liumiao$ sw_vers ProductName: Mac OS X ProductVersion: 10.15.2 BuildVersion: 19C57 liumiaocn:~ liumiao$ liumiaocn:~ liumiao$ cat test.text hello GREETING_MSG to use bash liumiaocn:~ liumiao$ sh test.sh Before sed -i hello GREETING_MSG to use bash sed: 1: "test.text": undefined label 'est.text' After sed -i hello GREETING_MSG to use bash liumiaocn:~ liumiao$
可以看到sed执行出错,这是因为在macOS上的sed在使用-i参数的时候需要额外指定一个标签用于备份源文件,设定为空就不会备份,将代码做如下修改即可:
liumiaocn:~ liumiao$ cp test.sh test.sh.org liumiaocn:~ liumiao$ vi test.sh liumiaocn:~ liumiao$ diff test.sh test.sh.org 16c16 < sed -i "" s@"${WORDS_REPLACE_SRC}"@"${WORDS_REPLACE_DST}"@g $FILE_TXT --- > sed -i s@"${WORDS_REPLACE_SRC}"@"${WORDS_REPLACE_DST}"@g $FILE_TXT liumiaocn:~ liumiao$
再次执行就会成功
liumiaocn:~ liumiao$ sh test.sh Before sed -i hello GREETING_MSG to use bash After sed -i hello liu miao to use bash liumiaocn:~ liumiao$总结
通过sed的-i参数在不同平台上的执行方式不同,如果需要在多个平台上进行兼容的情况下,或者将代码进行移植的情况下,都需要考虑,最好的方式当然还是使用POSIX的规范之内的部分,此部分之外的情况则需要多多考虑,很多常用的命令在不同平台下的表现可能会相差较大,这部分情况有时使用GNU版本的功能也是一个经常性的选择。