忽略SED中的空格,制表符和换行符

时间:2016-06-23 14:32:11

标签: linux bash sed

我尝试替换包含制表符和换行符的文件中的字符串。 shell文件中的命令看起来像这样:

FILE="/Somewhere"
STRING_OLD="line 1[ \t\r\n]*line 2"
sed -i 's/'"$STRING_OLD"'/'"$STRING_NEW"'/' $FILE

如果我手动删除换行符和制表符并只留下空格,那么我可以成功替换该文件。但如果我离开换行符,则SED无法找到$STRING_OLD且无法替换为新字符串

提前致谢

了Kobi

1 个答案:

答案 0 :(得分:2)

sed一次读取一行,并且通常在读取行时一次处理一行。但是,sed确实具有读取其他行并对合并结果进行操作的功能。有几种方法可以应用于您的问题,例如:

FILE="/Somewhere"
STRING_OLD="line 1[ \t\r\n]*line 2"
sed -n "1h;2,\$H;\${g;s/$STRING_OLD/$STRING_NEW/g;p}"

这或多或少地描述了您手动执行的操作:它连接文件的所有行(但保留换行符),然后一次性对整个缓冲区执行替换。但是,这确实假设文件很短(如果整个文件长度超过8192字节,POSIX不要求它工作)或者你使用的sed没有缓冲区大小限制,例如作为GNU sed。由于您标记了Linux,我假设可以假设GNU sed

详细说明:

  • -n选项会关闭行回显,因为我们会保存所有内容并在最后一个块中打印修改后的文本。
  • 有多个sed命令,以分号分隔,并且文字$字符已转义(对于shell):
    • 1h:处理第一行输入时,将“保留空间”替换为模式空间的内容(即第一行,不包括换行符)
    • 2,\$H:处理从第二行到最后一行的任何行时,将换行符添加到保留空间,然后添加模式空间的内容
    • \${g;s/$STRING_OLD/$STRING_NEW/g;p}:处理最后一行时,执行以下命令组:将保留空间复制到模式空间中;全局执行替换;打印图案空间的结果内容。

这是一种比较简单的方法,但是如果你需要容纳那些在缓冲容量方面不如GNU那么强大的sed,那么还有其他方法可以解决它。然而,那些开始变得难看。