【问题标题】:Delete date from string date ( [dd-mmm-yyyy hh:mm:ss] using SED使用 SED 从字符串日期 ( [dd-mmm-yyyy hh:mm:ss] 中删除日期
【发布时间】:2023-01-31 18:48:02
【问题描述】:

几天来我一直在与这个问题作斗争。 我有一个我正在尝试解析的程序的输出。

输出是在某些记录中添加了 2 个日期的日志流。

一个例子:

[27-Jan-2023 17:21:42] [2023-01-27 17:21:42] request.INFO: Matched route "home". {"route_parameters": "more data"
[27-Jan-2023 17:21:42] [2023-01-27 17:21:42] request.INFO: Matched route "home". {"route_parameters":{"_controller":"bla/bla/controller"},"request_uri":"http://local.myapp.com/"} []
[27-Jan-2023 17:21:42] [2023-01-27 17:21:42] security.INFO: Populated the TokenStorage with an anonymous Token. [] []
[27-Jan-2023 17:21:42] [2023-01-27 17:21:42] security.INFO: Populated the TokenStorage with an anonymous Token. [] []
[27-Jan-2023 17:21:42] [2023-01-27 17:21:42] data.DEBUG: SELECT s0_.id AS id0, s0_.name AS name1, s0_.value AS value2, FROM table s0_ WHERE s0_.active = ? [true] []
[2023-01-27 17:21:42] data.INFO: Some logs only include 1 date with a different format

像这样的常规正则表达式:/\[\d{2}-\w{3}-\d{4} \d{2}:\d{2}:\d{2}\] /g 将匹配第一个日期(包括括号)。但是我发现翻译成 SED 可以理解的表达方式真的很复杂。

我尝试了在 SO 和其他网站上找到的多种解决方案。

输入应该是这样的:

[27-Jan-2023 17:21:42] [2023-01-27 17:21:42] a
[2023-01-27 17:21:42] b 
[27-Jan-2023 17:21:42] [2023-01-27 17:21:42] c

和预期的输出:

[2023-01-27 17:21:42] a
[2023-01-27 17:21:42] b 
[2023-01-27 17:21:42] c

我尝试了多种表达方式,例如:

echo "[27-Jan-2023 17:21:42] [2023-01-27 17:21:42] something" | sed -e "s/\[[0-9]{2}-[A-Z][a-z]{3}-[0-9]{4} [0-9]{2}:[0-9]{2}:[0-9]{2}\] //"

或这个:

sed -e 's/\[[^][]*\] $/\1/'

它删除了括号内第一个日期的内容,但我想在日志仅包含 1 时保留第二个日期

我想我很接近,但我不确定我错过了什么。

回答

真的很难决定谁给它答案。两者都非常有帮助,但我决定使用收到的第一个,因为它既快速又优雅。第二个,我希望我能选择 2 个答案是有效的。采用我的方法并做了一个简单的改变......所以我真的很接近。

谢谢你们。 :)

【问题讨论】:

  • a、b、c从哪里来?
  • 它是旧应用程序 (PHP-FPM)\ 的输出 (Stream),很难更新。 :(
  • "[27-Jan-2023 17:21:42] [2023-01-27 17:21:42] something"中没有a or b or c
  • 这不是您想要的答案,而是:通过让所有设施以相同的方式记录它们的时间戳来对抗日志记录地狱。最好是 ISO-8901 格式。

标签: regex date sed


【解决方案1】:

你可以使用这个sed

echo "[27-Jan-2023 17:21:42] [2023-01-27 17:21:42] something" |
sed -E 's/^[[^]]+] ([[^]]+])//'

[2023-01-27 17:21:42] something

分解:

  • ^:开始
  • [[^]]+]:先匹配[...]文本
  • :匹配一个空格
  • ([[^]]+]):匹配第二个[...] 文本并在第 1 组中捕获

【讨论】:

  • 几乎,您的解决方案的唯一问题,也许我没有以更好的方式解释它,是我想在第二组之后保留 something。您的解决方案简单而优雅,:thumbs-up: 但删除了其余文本。只需要删除 2 个字符。 :D 's/^[[^]]+] ([[^]]+])//'
  • 是的,没错,只需删除 .* 即可满足该要求。
【解决方案2】:

你还差得远:

> echo -e "[27-Jan-2023 17:21:42] [2024-01-27 17:21:42] something
[2025-01-27 17:21:42] something else" | sed -E "s/[[0-9]{2}-[A-Z][a-z]{2}-[0-9]{4} [0-9]{2}:[0-9]{2}:[0-9]{2}] //"
[2024-01-27 17:21:42] something
[2025-01-27 17:21:42] something else

将月份缩写的 {3} 替换为 {2}

【讨论】:

  • 太棒了……但为什么是 2 个而不是 3 个?日期中的月份长度为 3 个字符?
  • 第一个字符:[A-Z],第二个和第三个:[a-z]{2}
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-04-07
  • 1970-01-01
  • 2012-05-03
  • 1970-01-01
  • 1970-01-01
  • 2017-10-11
  • 1970-01-01
相关资源
最近更新 更多