我想使用 sed 从文件中删除特定字符串:
sed -i 's/mystringtodelete //g'
但是,如果字符串中存在随机换行符,则此方法不起作用,例如:
我的
斯特林
格托德尔
埃特
有人知道解决方法吗?
答案1
在s
命令的正则表达式中,您需要将字符串的每个换行符转换为\n
.也就是说,像这样:
s/my\n\nstrin\n\ngtodel\n\nete\n//g
尤其要注意最后一个\n
,无论它是否确实必须是您的模式的一部分。
然后,还要记住这sed
是一个面向行的工具,这意味着默认情况下它将命令应用于每个输入线反过来,其输入中出现的每个换行符(换行符)都可以作为一个“输入行”。
因此,如果您需要匹配包含换行符的模式,您需要明确指示sed
。
一种替代方法是使用该-z
选项使其使用 NUL 字符(二进制 0x00)作为行分隔符,但如果您的输入数据无法完成此操作还包含 NUL。
如果你的输入是不是包含 NUL(并且您sed
实际上有这个-z
选项),那么您只需使用s
上面的命令即可sed -z
,一切就绪。
可以处理任何输入的替代方案基本上是将sed
行追加到其所谓的“保留空间”中,然后将您的模式应用到该内存区域。
如果您可以使用 的地址缩小应用替换的输入范围sed
,则可能会更好,因为某些sed
实现的保留空间空间有限。否则,您需要阅读整个输入,并希望它适合该区域。然而,例如 GNUsed
就没有限制,所以如果您使用的是常见的 Linux 系统,应该没问题。
假设您的输入无法缩小范围(即您的字符串可以出现在输入中的任何位置),则sed
适合您的命令可能是:
cat input_file | sed -ne '1h;1!H;${x;s/my\n\nstrin\n\ngtodel\n\nete\n//g;p}'
分解sed
的命令进行解释:
1h; # *copy* first line to hold-space
1!H; # *append* all non-first lines (i.e. all lines after the first) to hold-space
${x; # at the end of input move hold-space into regular pattern-space
s/my\n\nstrin\n\ngtodel\n\nete\n//g; # then apply substitution
p} # and print the resulting text