【问题标题】:sed for removing trailing zeroes - regex - nongreedy用于删除尾随零 - 正则表达式 - 非贪婪
【发布时间】:2011-08-02 18:21:10
【问题描述】:

我有一个文件,它有几行如下

ABCD|100.19000|90.100|1000.000010|SOMETHING
BCD|10.100|90.1|100.019900|SOMETHING

现在,在对此应用sed 之后,我希望输出如下(用于进一步处理)

ABCD|100.19|90.1|1000.00001|SOMETHING
BCD|10.1|90.1|100.0199|SOMETHING

即我希望从结果中删除所有尾随零(| 之前的零)。

我尝试了以下:(regtest是包含原始数据的文件如上图)

cat regtest | sed 's/|\([0-9]*\)\.\([0-9]*\)0*|/|\1\.\2|/g'

没有工作,因为我认为它很贪婪。

cat regtest | sed 's/|\([0-9]*\)\.\([0-9]*\)0|/|\1\.\2|/g'

会工作。但是,我将不得不在同一个文件上重复应用这个sed 命令来一个接一个地删除零。没有意义。

我该怎么办?谢谢!

【问题讨论】:

  • 当小数点后面只有零时,所需的输出是什么?没有小数点,只有小数点,还是小数点后跟一个零?
  • 这种情况不需要处理,因为我已经单独处理了......

标签: regex sed non-greedy


【解决方案1】:
$ echo "ABCD100|100.19000|90.100|1000.000010|STH" | \
  sed -r -e 's/\|/||/g' -e 's/(\|[0-9.]+[1-9])0+\|/\1|/g' -e 's/\|\|/|/g'
ABCD100|100.19|90.1|1000.00001|STH

【讨论】:

  • 谢谢。我有个问题。为什么这个和你建议的一样不起作用..? -> sed 's/([0-9])0+|/\1|/g' 。另外,如果我想确保只替换十进制值(比如我们有 ABCD000,它应该不理会)我应该怎么做?
  • 现在只对数字这样做。
  • Pyroscope, 10.10.100 也被这样替换了。请在下面查看我的 cmets (Chris)。对于我之前的评论,我使用的是普通的 sed 正则表达式而不是扩展的。我应该逃脱括号“(”和“)”,但即使我这样做,输出也与您之前建议的不匹配。那么,它与使用 -r aka extended 有关吗?
【解决方案2】:

如果你想依赖 |跟随要删除的零

cat regtest | sed -r 's/(00*)(\|)/\2/g' 

如果您想删除不以 .或一个数字

cat regtest | sed -r 's/(00*)([^.0-9])/\2/g'

(请注意,我使用 00* 而不是 0+ 以避免其他版本中没有 GNU sed 的独特功能)

编辑:对仅在小数点和管道之间删除尾随零的评论请求的回答:

cat regtest | sed -r 's/(\.[1-9])*(00*)(\|)/\1\3/g'

【讨论】:

  • 谢谢。我想确保只替换零以管道结尾但部分十进制值被替换。即 12.6200 或 0.100000 应该有效果。 ABCD0000 应该保持不变。可以做什么?
  • 猫注册测试 | sed -r 's/(\.[1-9])*(00*)(\|)/\1\3/g'
  • 谢谢。但是,这仍然没有达到我的预期。正如我在上面的评论中所说,只需替换十进制值。正确的值,如 10.900 或 9.9998800 等。在这里,如果我说 10.10.10(文件中的某些数据是这样的),那么它也会被替换。有什么可以补充的吗?
【解决方案3】:

使用 Perl 的extended regular expressions

perl -pe 's{\.\d*?\K0*(\||$)}{$1}g'

这会删除出现在(点和可选的一些数字)和(竖线或行尾)之间的零。

【讨论】:

  • 谢谢伙计。但是,我正在寻找一个 sed 解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-27
  • 2010-10-20
  • 2013-02-15
  • 1970-01-01
相关资源
最近更新 更多