【问题标题】:bash sed (or others) to substitute front anchored double space AND trailing non-printable characterbash sed (或其他)替换前锚定双空格和尾随不可打印字符
【发布时间】:2015-11-09 03:52:13
【问题描述】:

我有以下形式的行

line="  this is a line with 2 leading spaces and a trailing control char^M"

我想用 ^M 表示的两个前导空格和尾随控制字符都替换为空。

echo "${line}" | sed 's/^[[:space:]]*//' | tr -dc '[:print:]'
echo "${line}" | sed 's/^[[:space:]]*//' | sed 's/[^[:print:]]//'

两者都有效。我也试过

echo "${line}" | sed 's/^[[:space:]]*|[^[:print:]]//'

但这不起作用。

为什么最后一个表达式不起作用?
如何通过一次调用 sed 和一个正则表达式来完成此操作?
什么是首选解决方案,例如在效率方面?避免许多子shell更好吗?
有没有更好的解决方案?

【问题讨论】:

  • 您的表达式中缺少冒号(:print) + 您需要转义“或”运算符 (\|)
  • @ndn 我在询问之前阅读了该帖子,我认为它不是重复的,因为这个问题旨在找到一种通过单个 sed 调用执行多个替换的方法
  • @JiriKremser 我已经更正了“[:print]”错字,谢谢。很抱歉让大家耽搁了这么久......

标签: regex bash sed tr


【解决方案1】:

这个单一的 sed 应该可以工作:

sed 's/^[[:blank:]]*//; s/[[:cntrl:]]*$//' <<< "$line"
this is a line with 2 leading spaces and a trailing control char

【讨论】:

    【解决方案2】:
    sed 's/^[[:space:]]*|[^[:print]]//'
    

    不起作用,因为| 与自身匹配。 “或”在 sed 中拼写为 \|。 (而[:print] 应该是[:print:])。

    但这仍然不够,因为默认情况下 sed 只替换第一次出现;您需要 /g 标志来替换所有出现的情况:

    sed 's/^[[:space:]]*\|[^[:print:]]//g'
    

    但是您原来的正则表达式可能会产生一些意想不到的后果:[[:space:]] 匹配换行符,因此如果输入是一个或多个完整行,它将删除所有空行,而不仅仅是它们的内容。为防止这种情况,请改用[[:blank:]]

    sed 's/^[[:blank:]]*\|[^[:print:]]//g'
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-04
      • 2021-03-31
      • 1970-01-01
      • 1970-01-01
      • 2018-04-11
      相关资源
      最近更新 更多