【问题标题】:Getting unterminated 's' command with sed (bash)使用 sed (bash) 获取未终止的“s”命令
【发布时间】:2018-02-01 07:12:30
【问题描述】:

我的最终目标是在 /etc/ufw/before.rules 中的 COMMIT 行上方获取一堆文本。我正在尝试用以下内容替换 COMMIT: TEXT I WANT\nCOMMIT

我认为这是一个简单的 sed 命令:echo COMMIT | sed "s@COMMIT@${morerules}@g"

我已将变量morerules 设置为这样的字符串:

morerules="""
### Start HTTP ###
# Enter rule
-A ufw-before-input -p tcp --dport 80 -j ufw-http
-A ufw-before-input -p tcp --dport 443 -j ufw-http
# Limit connections per Class C
-A ufw-http -p tcp --syn -m connlimit --connlimit-above 50 --connlimit-mask 24 -j ufw-http-logdrop
# Limit connections per IP
-A ufw-http -m state --state NEW -m recent --name conn_per_ip --set
-A ufw-http -m state --state NEW -m recent --name conn_per_ip --update --seconds 10 --hitcount 20 -j ufw-http-logdrop
# Limit packets per IP
-A ufw-http -m recent --name pack_per_ip --set
-A ufw-http -m recent --name pack_per_ip --update --seconds 1 --hitcount 20 -j ufw-http-logdrop
# Finally accept
-A ufw-http -j ACCEPT
# Log
-A ufw-http-logdrop -m limit --limit 3/min --limit-burst 10 -j LOG --log-prefix \"[UFW HTTP DROP]\"
-A ufw-http-logdrop -j DROP
### End HTTP ##
"""

如您所见,我在引号中添加了反斜杠。设置变量成功。当我从上面echo COMMIT | sed "s@COMMIT@${morerules}@g" 运行命令时,输出如下:

sed: -e expression #1, char 9: unterminateds' 命令`

错误是我的字符串还是我的 sed 命令?另外,我知道其他人也遇到了这个错误,但他们的修复似乎都不起作用。

【问题讨论】:

标签: bash shell sed


【解决方案1】:

在替换文本中的每个换行符之前放置一个文字反斜杠,从而告诉sed 它应该被视为同一表达式的一部分:

orig=$'\n'; replace=$'\\\n'
sed "s@COMMIT@${morerules//$orig/$replace}@g"

(将值放在变量中可以更轻松地以跨多个 bash 版本的方式实现这一点)。

【讨论】:

  • 非常感谢!我以为字符串中的换行符会自动转换,但它被解释为多个命令是有道理的。
猜你喜欢
  • 2019-05-04
  • 2015-09-25
  • 1970-01-01
  • 2016-07-29
  • 1970-01-01
  • 2013-06-11
  • 2012-05-05
  • 2012-07-10
  • 2013-11-27
相关资源
最近更新 更多