忽略 SED 中的空格、制表符和新行 [英] Ignore spaces, tabs and new line in SED

查看:117
本文介绍了忽略 SED 中的空格、制表符和新行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图替换包含制表符和换行符的文件中的字符串.shell 文件中的命令如下所示:

I tried to replace a string in a file that contains tabs and line breaks. the command in the shell file looked something like this:

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

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

if I manually remove the line breaks and the tabs and leave only the spaces then I can replace successfully the file. but if I leave the line breaks then SED is unable to locate the $STRING_OLD and unable to replace to the new string

提前致谢

科比

推荐答案

sed 一次读取一行,通常在读取时也一次处理一行.但是,sed 确实具有读取附加行并对组合结果进行操作的功能.有多种方法可以解决您的问题,例如:

sed reads lines one at a time, and usually lines are also processed one at a time, as they are read. However, sed does have facilities for reading additional lines and operating on the combined result. There are several ways that could be applied to your problem, such as:

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.

That that does more or less what you describe doing manually: it concatenates all the lines of the file (but keeps newlines), and then performs the substitution on the overall buffer, all at once. That does assume, however, either that the file is short (POSIX does not require it to work if the overall file length exceeds 8192 bytes) or that you are using a sed that does not have buffer-size limitations, such as GNU sed. Since you tagged Linux, I'm supposing that GNU sed can be assumed.

详细说明:

  • -n 选项关闭行回显,因为我们保存所有内容并在最后将修改后的文本打印在一个块中.
  • 有多个 sed 命令,用分号分隔,并带有转义的文字 $ 字符(对于 shell):
    • 1h:处理输入的第一行时,将保持空间"替换为模式空间的内容(即第一行,不包括换行符)
    • 2,\$H:当处理从第二行到最后一行的任何一行时,在保持空间追加一个换行符,然后是模式空间的内容
    • \${g;s/$STRING_OLD/$STRING_NEW/g;p}:处理最后一行时,执行这组命令:将hold space复制到pattern space;全局执行替换;打印模式空间的结果内容.
    • the -n option turns off line echoing, because we save everything up and print the modified text in one chunk at the end.
    • there are multiple sed commands, separated by semicolons, and with literal $ characters escaped (for the shell):
      • 1h: when processing the first line of input, replace the "hold space" with the contents of the pattern space (i.e. the first line, excluding newline)
      • 2,\$H: when processing any line from the second through the last, append a newline to the hold space, then the contents of the pattern space
      • \${g;s/$STRING_OLD/$STRING_NEW/g;p}: when processing the last line, perform this group of commands: copy the hold space into the pattern space; perform the substitution, globally; print the resulting contents of the pattern space.

      这是一种更简单的方法,但是如果您需要适应 sed 在缓冲区容量方面不如 GNU 的能力,那么还有其他方法可以解决这个问题.不过,那些开始变得丑陋.

      That's one of the simpler approaches, but if you need to accommodate seds that are not as capable as GNU's with regard to buffer capacity then there are other ways to go about it. Those start to get ugly, though.

      这篇关于忽略 SED 中的空格、制表符和新行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆