awk
我需要一些关于正则表达式的帮助或建议。我有一个结构不规则的数据输入文件。为了正确解析该文件,我需要识别以下形式的行:
@ 8/1/17, 10:04 PM
具有此模式的线条标志着完整交易的结束。它只是一个日期和时间戳,前面有一个空格和字符@
。
我拼凑了一个似乎与“大多数”用法匹配的正则表达式:
\W\@\W[0-9]{1,2}\/[0-9]{1,2}\/[0-9]{1,2}\,\W[0-9]{1,2}\:[0-9]{2}\W[AP]M
然而,当用在下面的语句中时,它似乎不匹配awk
:
$ awk 'match($0, /\W\@\W[0-9]{1,2}\/[0-9]{1,2}\/[0-9]{1,2}\,\W[0-9]{1,2}\:[0-9]{2}\W[AP]M/) {print $0}' testfile2.txt
我的系统(莫哈韦Macos) 有一个旧版本awk
awk version 20070501
。
我还发现:
grep -e
无法将此模式与 中的任何行匹配testfile2.txt
,但egrep
和grep -E
确实匹配我期望它们匹配的行。awk 'match($0, /\@/) {print $0}' testfile2.txt
确实匹配(并打印)预期的行,但我不能依赖单个字符!
这是 testfile2.txt:
+13054261988:将数据转发到主存储库
@ 1/7/18,下午 4:21
+16744774911:使用此 URL:https://www.repo-prime.ga/
@ 1/7/18,下午 4:22
+13054261988:可以。密码可以吗?
@ 1/7/18,下午 6:12
+16744774911:不,对所有交易使用 2FA
@ 1/7/18,晚上 8:56
+13054261988:使用 Google 的身份验证器?如果是这样,将需要更多信息。
@ 1/7/18, 9:36 PM
+13054261988:尽快回复,我有需要上传的交易。
@ 2018 年 1 月 7 日,晚上 9:46
我的正则表达式在使用中无法匹配是awk
由于我在语句中看不到的错误awk
,还是由于正则表达式本身、两者的组合等?
答案1
似乎非常旧的 awk 版本没有{…}
能力。
这个旧的正则表达式语法应该在任何 awk 中匹配:
awk '/@ [0-9][0-9]?\/[0-9][0-9]?\/[0-9][0-9]?, [1-2]?[0-9]:[0-6][0-9] [AP]M/' file
如果您的 awk 可以匹配像 之类的括号表达式[[:blank:]]
,则可以使正则表达式更加灵活:
awk '/@[[:blank:]][0-9][0-9]?\/[0-9][0-9]?\/[0-9][0-9]?,[[:blank:]][1-2]?[0-9]:[0-6][0-9][[:blank:]][AP]M/' file
如果匹配一个(或多个)数字就足够了(我不明白为什么不可以),您可以使用更短的正则表达式:
awk '/@ [0-9]+\/[0-9]+\/[0-9]+, [1-2]?[0-9]:[0-6][0-9] [AP]M/' file
如果需要,您可以添加开始^
和结束$
以使正则表达式更具限制性。
我没有使用match
这样简单的行匹配,但相同的正则表达式可以与该函数完美配合。
答案2
- 为什么之前严格匹配
/\W
(非单词字符)@
?就像你的文本文件@
位于行的开头一样 - 不需要将字符转义为
\@
,\,
,:
(它们不是特殊字符) match()
如果只需要匹配模式,调用是多余的
$ awk '/^@ [0-9]{1,2}\/[0-9]{1,2}\/[0-9]{1,2}, [0-9]{1,2}:[0-9]{2} [AP]M/' file
@ 1/7/18, 4:21 PM
@ 1/7/18, 4:22 PM
@ 1/7/18, 6:12 PM
@ 1/7/18, 8:56 PM
@ 1/7/18, 9:36 PM
@ 1/7/18, 9:46 PM