【问题标题】:Sed to replace single quotation marksed替换单引号
【发布时间】:2021-08-10 16:08:22
【问题描述】:

我正在为一件简单的事情而发疯。我写了以下行,效果惊人:

name=$(echo $name | sed 's/"//g' | sed 's/^ //' | sed 's/ $//' | sed "s/'/\\\'/")

我试图将 sed 减少到只有一个命令而不是四个,我编写了以下行,但我无法使其工作:

name=$(echo $name | sed 's/"//g; s/^ //; s/ $//; s/\'/\\\'/g')

我明白了:

sed: 1: "s/"//g; s/^ //; s/ $//; ...": unterminated substitute in regular expression

我做错了什么?我看不到语法错误,我尝试重写了很多次,有 4 个 sed 的行有效,但是我尝试将所有内容放在一个 sed 中却没有。

非常感谢您的帮助!

【问题讨论】:

  • 使用好的编辑器。甚至在这里在 stackoverflow 上着色也在暗示你。
  • 您应该双引号引用变量引用(例如 echo "$name" 而不仅仅是 echo $name),以防止在值到达 sed 之前进行奇怪的解析。请参阅"I just assigned a variable, but echo $variable shows something else"(但请注意,这并不适用于echo;它几乎适用于所有地方)。 shellcheck.net 擅长发现此类常见错误。
  • 好建议戈登,谢谢!

标签: sed


【解决方案1】:

无论您现在使用多少转义符,都不能在单引号字符串中嵌入单引号:3.1.2.2 Single Quotes

您可以使用 sed 的 -e 选项链接命令并为您提供最大的引用灵活性:

sed -e 's/"//g' -e 's/^ //' -e 's/ $//' -e "s/'/\\\'/"
# or
sed -e 's/"//g; s/^ //; s/ $//' -e "s/'/\\\'/"

【讨论】:

  • 谢谢Glenn,我一开始错过了选项-e,然后我不知道我不能在SQM中使用单引号,然后转义完全没用,现在一切都清楚了,谢谢非常感谢您的帮助!
【解决方案2】:

这可能对你有用(GNU sed):

sed -E 's/^ |"| $//g;s/'\''/\\&/g' file

使用交替删除行首/尾的空格或双引号。

用转义的单引号替换单引号。

不可能通过单个替换获得解决方案,因为替换的 RHS 在四种情况之一中是不同的,即前 3 种情况删除字符串,而第四种情况添加一个。

如果您打算删除单引号,请使用:

sed -E 's/^ |["'\'']| $//g' file

【讨论】:

  • @EdMorton 哎呀!
【解决方案3】:

您还可以在任何需要切换引号的地方邻接引号。请注意插值,通常使用双引号:

代替

name=$(echo $name | sed 's/"//g; s/^ //; s/ $//; s/\'/\\\'/g')

$ name=$(echo $name | sed 's/"//g; s/^ //; s/ $//;'" s/\'/\\\'/g")

虽然我认为你真正想要的可能是

$ name=$(echo $name | sed 's/"//g; s/^ //; s/ $//;'" s/'//g")

相邻引号就像任何其他相邻字符一样。由于没有中间空格,它们构成了一个连续的字符串。

【讨论】:

  • 我从未见过变量前有空格的 $,我需要阅读它。非常感谢詹姆斯,感谢您的帮助。
  • @Renato 行首的$ 只是PS1 中设置的一个非常常见的提示,它与变量或命令的任何部分无关。跨度>
  • 对不起詹姆斯,我以为是脚本的一部分,这显然是 bash 用户符号,再次抱歉。
  • echo $name 真的很糟糕。试试a=' -n a b c '; echo $a(带有多个空格),你会得到a b c(带有单个空格)。更好的是echo "$name"。更好的是sed ... <<< "$name" 没有回声。
  • @Wiimm,除非问题涉及泛化或可移植性,否则我认为在 SO 答案中没有理由提供完全通用的代码。完美的准确性是以清晰度为代价的;一个简单的直截了当的答案比一个完全笼统的答案要好。 (不过,我不推荐 <<<,因为它特定于 bash。)
【解决方案4】:

您可以使用 bash 引用的第三种方法:$'...'。在这里,像 C 一样的转义是可能的。所以你的 sed 命令可以是:

sed $'s/"//g; s/^ //; s/ $//; s/\'/\\\'/g'

但如果你愿意,输入 a'b 变成 a\'b,然后使用

sed $'s/"//g; s/^ //; s/ $//; s/\'/\\\\\'/g'

分析\\\\\':bash 将其读取为\\'。 sed 将其读取为\'

【讨论】:

  • 我需要阅读有关$'...' 的信息,因为我以前从未见过它。谢谢 Wiimm,我感谢您的建议!
猜你喜欢
  • 1970-01-01
  • 2017-08-05
  • 2011-06-19
  • 2022-01-27
  • 2016-08-10
  • 1970-01-01
  • 2011-12-25
  • 2020-12-23
  • 2014-03-24
相关资源
最近更新 更多