【问题标题】:Bash one-liner to replace all [:punct:] characters with those same characters escapedBash one-liner 用转义的相同字符替换所有 [:punct:] 字符
【发布时间】:2015-09-18 12:12:48
【问题描述】:

我目前对 bash 的一种未解决的问题是如何替换 [:punct:] 类中的所有字符,即

[!"#$%&'()*+,\-./:;<=>?@[\\\]^_`{|}~]

,每个都用反斜杠转义相同的字符。比如我想让^h?e.l*l+o:变成\^h\?e\.l\*l\+o\:

我可以通过循环以多线方式进行。有没有可能用更简洁优雅的方式来做呢?

谢谢, 卢卡

【问题讨论】:

  • 您确定要转义 all 标点符号,还是只转义在某些情况下具有特殊含义的标点符号?用例是什么? (可能有各种简单的替代方案,具体取决于为什么它们需要被转义。)
  • this question 有帮助吗?
  • @chepner 你可能是对的。为了简单起见,我尝试转义所有标点符号,但是如果转义,撇号 ' (可能还有一些我尚未测试过的其他字符)存在问题,它与自身不再匹配。我基本上想转义正则表达式和 glob 元字符。最简单的解决方案是删除它们,如[!#$%&amp;()*+,\-./:;&lt;=&gt;?@[\\\]^_{|}~]。还有其他方法吗?
  • 是的,还有许多其他方法,如上面@EtanReisner 引用的帖子中的两个 cmets。谢谢,我学到了很多。

标签: regex bash string-substitution


【解决方案1】:

你能用sed吗?

echo '^h?e.l*l+o:' | sed 's/\([[:punct:]]\)/\\\1/g'

没有sed,我想不出除了循环字符之外的任何东西:

s='^h?e.l*l+o:'
o=''
for ((i=0; i<${#s}; i++)) ; do
    c=${s:i:1}
    [[ $c =~ [[:punct:]] ]] && o+=\\
    o+=$c
done
echo "$o"

另一种可能是使用Perl的quotemeta

echo '^h?e.l*l+o:' | perl -lne 'print quotemeta'

-l 处理换行符。 -n逐行处理输入。

【讨论】:

  • 是的,我相信它可以用 sed 完成,这就是我问的原因,但我不知道怎么做,因为我对 bash、sed、awk 等还是很陌生。你能添加一个关于它是如何工作的以及\1 是什么意思的解释?这是有史以来最快的回复,谢谢!
  • @the_eraser:检查更新 - 这是您的解决方案吗?
  • @the_eraser:\1是第一个匹配组,即第一对\(...\)匹配的子串。
  • 好的,谢谢。是的,我解决了一个 for 循环,对字符串进行切片和=~,但是使用 sed 会好很多。
  • 只能使用&amp;,没有匹配的组。
猜你喜欢
  • 2018-04-05
  • 1970-01-01
  • 1970-01-01
  • 2011-06-01
  • 1970-01-01
  • 2021-06-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多