用sed替换超过150000个字符

时间:2015-03-26 03:19:49

标签: regex bash shell sed grep

我想将此LONG字符串替换为sed
我从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个字符。

2 个答案:

答案 0 :(得分:2)

在大多数系统中,ARG_MAX的值足以处理150k而没有问题,但重要的是要注意虽然限制被称为ARG_MAX并且错误消息表明命令行太长,实际限制是参数和所有(导出的)环境变量的大小之和。此外,Linux对单个参数字符串施加了128k(131,072字节)的限制。超过任何这些限制会触发E2BIG的错误返回,其打印为"参数列表太长"。

在任何情况下,bash内置函数都不受限制,因此您应该能够将命令作为命令文件提供给sed:

echo "s|$var||g" | sed -f - -i /home/lazuardi/project/assets/static/admin/bootstrap3/css/bootstrap.css.map
但是,这可能对你没什么帮助。您的变量充满了正则表达式元字符,因此它与字符串本身不匹配。您需要清理它才能将其用作正则表达式。 但是,这可能是一种更清晰的编辑方式。

答案 1 :(得分:2)

实际试图在这里完成什么? 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%\([^:]\)//.*%\1%' file

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

如果您希望var中的评论出于其他原因,grep也可以得到显着清理。 (显然,你在执行替换之前运行它。)

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

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