用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,}
是 *
.)
我想用 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,}
是 *
.)