我有一个包含以下格式数据的文本文件:
2020-01-01 00:00:00 @gibberish - key1:{value1}, unwanted key2:{value2}, unwanted key3:{value3}
我想单独收集开始和键值对中的时间戳。喜欢下面的
2020-01-01 00:00:00,key1:{value1},key2:{value2},key3:{value3}
我能够编写一个可以选择所需值的正则表达式脚本(在 visual studio 代码中工作)
^([0-9 :-]+)|([0-9A-z,_-]+):\{(.*?)\}
(第一个模式选择时间戳,第二部分选择键值模式)
现在,如何选择不匹配的部分并使用 sed 将其删除?
注意:我尝试使用 egrep 来匹配所需的模式并将其写入新文件。但是每个匹配的字符串都写在一个新行而不是保持在同一行。这对我没有用。
egrep -o '^([0-9 :-]+)|([0-9A-z,_-]+):\{(.*?)\}' source.txt > target.txt
最佳答案
从最后到第一,我可以评论:
egrep
:是的,这是设计的行为 -egrep
可能不是您想要使用的。sed
:重要的是要注意sed
使用 POSIX 正则表达式,它比现在人们对正则表达式的期望更简单,限制也更多。在过去的几十年中,大多数新样式(增强的、perl 兼容的等)正则表达式工作都是在 Perl 中完成的,它在 UNIX 系统上很容易获得,并且可能是您想要使用的(但也要注意,在 macOS 中,与所有 Apple 分发的 UNIX 程序一样,那里的perl
二进制文件已经过时了。它可能仍会执行您想要的操作,但请注意)。- 您的正则表达式使用范围
[A-z]
,这很奇怪并且在我的egrep
或sed
中不起作用 - 我理解你想做什么,但它不应该在实际使用字符集的系统中工作(我不确定 Visual Studio 在这个范围内做了什么,但它对我来说似乎很疯狂)。您可能打算使用[A-Za-z]
。
我会像这样使用 Perl 编写这个东西:
perl -nle '@res = (); while(m/^([0-9 :-]+\d)|([0-9A-Za-z,_-]+:\{[^}]+\})/g) {
push @res, "$1$2";
};
print join ",",@res' < source.txt > target.txt
关于regex - 使用sed删除不匹配的部分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66006507/