用sed替换超过150000个字符

Replace more than 150000 character with sed

我想用 sed
替换这个 LONG 字符串 我从 grep 中获取了字符串,并将其存储到变量 var
中 这是我的 grep 命令和我的 var 变量:

var=$(grep -P -o "[^:]//.{0,}" /home/lazuardi/project/assets/static/admin/bootstrap3/css/bootstrap.css.map | grep -P -o "//.{0,})  

这是 grep 的输出:string

然后我尝试用sed命令替换它

sed -i "s|$var||g" /home/lazuardi/project/assets/static/admin/bootstrap3/css/bootstrap.css.map

但它给我输出 bash: /bin/sed: Argument list too long

如何更换?

注意:该字符串一行有 183544 个字符。

如今在大多数系统上,ARG_MAX 的值足以毫无问题地处理 150k,但重要的是要注意,虽然调用限制 ARG_MAX 并且错误消息表明命令行太长,真正的限制是参数大小和所有(导出的)环境变量的总和。此外,Linux 对单个参数字符串施加了 128k(131,072 字节)的限制。超过这些限制中的任何一个都会触发错误 return of E2BIG,打印为 "Argument list too long".

在任何情况下,bash 内建函数不受限制,因此您应该能够将命令作为命令文件输入 sed:

echo "s|$var||g" | sed -f - -i /home/lazuardi/project/assets/static/admin/bootstrap3/css/bootstrap.css.map

不过,这可能对您帮助不大。您的变量充满了正则表达式元字符,因此它不会匹配字符串本身。您需要清理它以便能够将其用作正则表达式。 不过,可能有更简洁的方法来进行该编辑。

实际上想在这里完成什么? sed 是面向行的,所以你不能替换多行字符串(即使你用 \n 替换文字换行符也不能......好吧,有很多方法可以写 sed有效替换一系列行的脚本,但它很快就会受到折磨。

bash$ var=$(head -n 2 /etc/mtab)

bash$ sed "s|$var||" /etc/mtab
sed: -e expression #1, char 25: unterminated `s' command

bash$ sed "s|${var//$'\n'/\n}||" /etc/mtab | diff -u /etc/mtab -

bash$ # (didn't replace anything, so no output)

作为解决方法,您可能想要的可以通过将$var中的换行符替换为\|(或者可能只是|,取决于你的 sed 方言)与上面演示的类似,但你仍然会遇到 ARG_MAX 限制并且有一堆其他讨厌的皱纹需要解决,所以我们不要走那里。

然而,您正在尝试的事情可以由 sed 自己完成,完全靠自己。您不需要字符串列表;毕竟,sed 也可以处理正则表达式(而且您使用的正则表达式实际上不需要 Perl 扩展,因此 -P 选项基本上是多余的)。

sed -i 's%\([^:]\)//.*%%' file

有一个小警告——如果前面有和没有 : 的字符串出现,您的原始命令将全部替换它们(如果有效的话),而这个只会替换前面没有冒号的事件。这意味着行首的注释不会被触及——如果你也想删除它们,只需添加一个行锚点作为替代; sed -i 's%\(^\|[^:]\)//.*%%' file

如果您出于其他原因想要 var 中的注释,grep 也可以进行大量清理。 (显然,您会 运行 在执行替换之前这样做。)

var=$(grep -P -o '[^:]\K//.*' file)

\K 扩展是真正需要 -P 的扩展。当然,还有通用、清晰、标准、可读、可移植、明显、简单的编写方式 {0,}*.)