【问题标题】:sed expression , char xx: Invalid range end error caused by hyphensed 表达式,char xx:由连字符引起的无效范围结束错误
【发布时间】:2014-09-30 00:06:04
【问题描述】:

给定一个文件:

2014-08-01 20:13:17.666 xxxxxxxxxx
2014-08-01 20:13:17.666 xxxxxxxxxx
2014-08-01 20:13:17.666 xxxxxxxxxx
......

我正在尝试使用 sed 删除微秒:

GNU sed version 4.2.1
Copyright (C) 2009 Free Software Foundation, Inc.

以下失败并显示错误消息“sed: -e expression #1, char 38: Invalid range end”

sed 's/\([0-9][0-9\- :]*\)\.[0-9]\{3\}/\1/g' < a.csv

然而,vi a.csv 并搜索

\([0-9][0-9\- :]*\)\.[0-9]\{3\}

工作正常。

根本原因是转义的连字符。如果我删除转义的连字符,sed 不会抱怨,但它不会匹配预期的模式。我尝试了不同的转义连字符的方法,但无济于事。

解决方法是显式写出整个日期时间格式,如下所示:

sed 's/\([0-9][0-9]*-[0-9][0-9]-[0-9][0-9] [0-2][0-9]:[0-5][0-9]:[0-5][0-9]\)\.[0-9]\{3\}/\1/g'

解决方法看起来既丑陋又麻烦。我确实意识到 sed 和 vi 之间的底层 RE 引擎是不同的。不过,我喜欢

  1. 了解为什么在 sed 中转义连字符也会失败
  2. 如何修改 sed 的 RE 以使其更优雅。

sed error "Invalid range end" 相关但未由sed error "Invalid range end"解决

【问题讨论】:

  • 您可以将[0-9] 缩短为\d,如果您有[0-9][0-9],您可以使用\d{2}
  • 谢谢费德。我刚开始使用 RE 并欣赏上述改进。

标签: regex bash unix sed


【解决方案1】:

在字符类中,连字符必须是第一个或最后一个。尝试用反斜杠转义它不起作用(而是将反斜杠添加到类中)。

有多种sed 方言和多种其他正则表达式实现,它们的工作方式不同,但在这种情况下,诊断相当简单。和修复:

sed 's/\([0-9][-0-9 :]*\)\.[0-9]\{3\}/\1/' < a.csv

(我还删除了 /g 标志,因为它在这里似乎是多余的。当然,这种模式的每一行出现的次数不超过一次?)

【讨论】:

  • 另外,我不明白您为什么要在句号之前允许使用连字符。它应该始终是冒号、两位数、句点、微秒;不应该吗?但这并不能回答您的问题(-:
猜你喜欢
  • 2013-05-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-08
  • 1970-01-01
  • 2015-08-28
  • 2015-04-16
  • 1970-01-01
相关资源
最近更新 更多