我尝试替换包含制表符和换行符的文件中的字符串。 shell文件中的命令看起来像这样:
FILE="/Somewhere"
STRING_OLD="line 1[ \t\r\n]*line 2"
sed -i 's/'"$STRING_OLD"'/'"$STRING_NEW"'/' $FILE
如果我手动删除换行符和制表符并只留下空格,那么我可以成功替换该文件。但如果我离开换行符,则SED
无法找到$STRING_OLD
且无法替换为新字符串
提前致谢
了Kobi
答案 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
,那么还有其他方法可以解决它。然而,那些开始变得难看。