删除字符串直到第一次出现右括号

Posted

技术标签:

【中文标题】删除字符串直到第一次出现右括号【英文标题】:Deleting a string upto first occurrence of right bracket 【发布时间】:2021-06-07 13:57:53 【问题描述】:

我有一个看起来像这样的文件:

[----------] 7 tests from RouteGenSetup
[ RUN      ] RouteGenSetup.AcceptTATTest
[2021-03-08 22:55:53.937] [info] TimeSlotAssignmentTable::LogTATRow(Add): 1.1 -> 2.1, rounds: LLLLLL, pattern: TR
[2021-03-08 22:55:53.937] [info] TimeSlotAssignmentTable::LogTATRow(Add): 1.1 -> 5.1, rounds: LLLLLL, pattern: TR
[2021-03-08 22:55:53.937] [info] TimeSlotAssignmentTable::LogTATRow(Add): 6.1 -> 7.1, rounds: LLLLLL, pattern: TR
[       OK ] RouteGenSetup.AcceptTATTest (0 ms)
[ RUN      ] RouteGenSetup.BlockLinksTest
[2021-03-08 22:55:53.937] [error] TimeSlotAssignmentTable::LogTATRow(Add): 1.1 -> 2.1, rounds: LLLLLL, pattern: TR
[2021-03-08 22:55:53.938] [error] TimeSlotAssignmentTable::LogTATRow(Add): 1.1 -> 5.1, rounds: LLLLLL, pattern: TR

我想去掉日期和时间戳(例如,[2021-03-08 22:55:53.937])。为此,我尝试使用以下sed 命令:

sed -i '/^\[2021-/s/^.*\]\ //1' output.txt

但是,时间戳右侧的 [info][error] 括号也会被删除:

[----------] 7 tests from RouteGenSetup
[ RUN      ] RouteGenSetup.AcceptTATTest
TimeSlotAssignmentTable::LogTATRow(Add): 1.1 -> 2.1, rounds: LLLLLL, pattern: TR
TimeSlotAssignmentTable::LogTATRow(Add): 1.1 -> 5.1, rounds: LLLLLL, pattern: TR
TimeSlotAssignmentTable::LogTATRow(Add): 6.1 -> 7.1, rounds: LLLLLL, pattern: TR
[       OK ] RouteGenSetup.AcceptTATTest (0 ms)
[ RUN      ] RouteGenSetup.BlockLinksTest
TimeSlotAssignmentTable::LogTATRow(Add): 1.1 -> 2.1, rounds: LLLLLL, pattern: TR
TimeSlotAssignmentTable::LogTATRow(Add): 1.1 -> 5.1, rounds: LLLLLL, pattern: TR

当我尝试时

sed -i '/^\[2021/s/[^\]]*//' output.txt

第一个左括号删除而不是第一个右括号:

[----------] 7 tests from RouteGenSetup
[ RUN      ] RouteGenSetup.AcceptTATTest
2021-03-08 22:55:53.937] [info] TimeSlotAssignmentTable::LogTATRow(Add): 1.1 -> 2.1, rounds: LLLLLL, pattern: TR
2021-03-08 22:55:53.937] [info] TimeSlotAssignmentTable::LogTATRow(Add): 1.1 -> 5.1, rounds: LLLLLL, pattern: TR
2021-03-08 22:55:53.937] [info] TimeSlotAssignmentTable::LogTATRow(Add): 6.1 -> 7.1, rounds: LLLLLL, pattern: TR
[       OK ] RouteGenSetup.AcceptTATTest (0 ms)
[ RUN      ] RouteGenSetup.BlockLinksTest
2021-03-08 22:55:53.937] [error] TimeSlotAssignmentTable::LogTATRow(Add): 1.1 -> 2.1, rounds: LLLLLL, pattern: TR
2021-03-08 22:55:53.938] [error] TimeSlotAssignmentTable::LogTATRow(Add): 1.1 -> 5.1, rounds: LLLLLL, pattern: TR

正在尝试

sed -i '/^\[2021/s/^[^\]]*\]//' output.txt

不会产生任何变化。我不知道如何解决这个问题。我尝试了许多类似帖子中推荐的东西,但都没有成功。

注意:这不是sed - regex square brackets detection in Linux 的重复,因为这里的问题是不同的:仅匹配字符串开头和第一个] 之间的子字符串+ 空格如果行开始带有一定的前缀。

sed replace a word at a line which begins with a specific pattern using 没有解释如何获取以特殊字符开头的行,然后匹配从开始到第一个 ] + 空格的字符串。

【问题讨论】:

【参考方案1】:

你可以使用

sed -i '/^\[2021-/s/^[^]]*] //' file

这里,

/^\[2021-/ - 查找以 [2021- 开头的行 s/^[^]]*] // - 匹配除 ] 以外的任何零个或多个字符,从字符串的开头到第一个 ],然后是空格并删除这些匹配项(因为 RHS 为空)。

注意[^]] 是一个否定括号表达式,它匹配除] 之外的任何字符。由于括号表达式不支持正则表达式转义序列,] 必须是括号表达式中的第一个字符,您不能在括号表达式中的任何位置使用\]

见an online demo:

s='[----------] 7 tests from RouteGenSetup
[ RUN      ] RouteGenSetup.AcceptTATTest
[2021-03-08 22:55:53.937] [info] TimeSlotAssignmentTable::LogTATRow(Add): 1.1 -> 2.1, rounds: LLLLLL, pattern: TR
[2021-03-08 22:55:53.937] [info] TimeSlotAssignmentTable::LogTATRow(Add): 1.1 -> 5.1, rounds: LLLLLL, pattern: TR
[2021-03-08 22:55:53.937] [info] TimeSlotAssignmentTable::LogTATRow(Add): 6.1 -> 7.1, rounds: LLLLLL, pattern: TR
[       OK ] RouteGenSetup.AcceptTATTest (0 ms)
[ RUN      ] RouteGenSetup.BlockLinksTest
[2021-03-08 22:55:53.937] [error] TimeSlotAssignmentTable::LogTATRow(Add): 1.1 -> 2.1, rounds: LLLLLL, pattern: TR
[2021-03-08 22:55:53.938] [error] TimeSlotAssignmentTable::LogTATRow(Add): 1.1 -> 5.1, rounds: LLLLLL, pattern: TR'
sed '/^\[2021-/s/^[^]]*] //' <<< "$s"

输出:

[----------] 7 tests from RouteGenSetup
[ RUN      ] RouteGenSetup.AcceptTATTest
[info] TimeSlotAssignmentTable::LogTATRow(Add): 1.1 -> 2.1, rounds: LLLLLL, pattern: TR
[info] TimeSlotAssignmentTable::LogTATRow(Add): 1.1 -> 5.1, rounds: LLLLLL, pattern: TR
[info] TimeSlotAssignmentTable::LogTATRow(Add): 6.1 -> 7.1, rounds: LLLLLL, pattern: TR
[       OK ] RouteGenSetup.AcceptTATTest (0 ms)
[ RUN      ] RouteGenSetup.BlockLinksTest
[error] TimeSlotAssignmentTable::LogTATRow(Add): 1.1 -> 2.1, rounds: LLLLLL, pattern: TR
[error] TimeSlotAssignmentTable::LogTATRow(Add): 1.1 -> 5.1, rounds: LLLLLL, pattern: TR

【讨论】:

以上是关于删除字符串直到第一次出现右括号的主要内容,如果未能解决你的问题,请参考以下文章

20165104-Java第一次结对编程练习

栈应用:有效的括号(第一题)

用另一个字符串替换第一次和最后一次出现的字符串

括号匹配方案

LeetCode 301 删除无效的括号[dfs 字符串] HERODING的LeetCode之路

重复删除子字符串后查找剩余字符串