首先,我是新手,所以我仍在学习..
数据集文件有点像这样
101 80 10 27598 General Tao Vancouver 01:45:10 01:46:10 00:43:00 00:59:59 01:25:10
Run Code Online (Sandbox Code Playgroud)
我正在尝试检查时间以确保它们与 的格式匹配/d/d:/d/d:/d/d
,如果它与该正则表达式不匹配,则它会打印出该行的第一个数字(在这种情况下为 101)
我一直在 CLI 中尝试一种衬垫,但无济于事。
grep '/d/d:/d/d:/d/d' file.txt
Run Code Online (Sandbox Code Playgroud)
即使为此也没有任何反应
edit1:在数据集中,有些数据看起来像 01:4510 或类似的
我希望得到的示例输出是:
104 80 10 27598 BigBelly Vancouver 01:4510 01:46:10 00:43:00 00:59:59 01:25:10
Run Code Online (Sandbox Code Playgroud)
您一定一直在考虑匹配十进制数字的正则\d
表达式运算符perl
。但请注意,很少有grep
实现支持它。标准等价物是[[:digit:]]
。
一些grep
实现支持\d
if 传递一个-P
选项(使用类似 perl 的正则表达式而不是基本的正则表达式)。
所以有了这些,你可以这样做:
grep -Pv '\d\d:\d\d:\d\d' < file.txt
Run Code Online (Sandbox Code Playgroud)
返回不包含与该模式匹配的字符串的行。
(请注意,它们是反斜杠而不是正斜杠)
或者:
grep -Pv '(\s+\d\d:\d\d:\d\d){5}\s*$' < file.txt
Run Code Online (Sandbox Code Playgroud)
对于不以 5 个这样的时间戳结尾的行。
要在这种情况下返回第一个字段,您可以改为grep
执行(使用也支持 的实现-o
)
grep -Po '^(?!.*(\s+\d\d:\d\d:\d\d){5}\s*$)\s*\K\S+' < file.txt
Run Code Online (Sandbox Code Playgroud)
这次使用否定前瞻 perl 正则表达式运算符而不是使用grep
's -v
。
该grep
MACOS(你说你正在使用,现在我已经删除的linux的从你的问题的标签,取而代之的是MacOS的),恰好是那几个,其基本的正则表达式支持一个\d
,但它不支持-P
,那么那些(?!...)
和\K
运营商不可有。
一个标准(更清晰)的等价物是:
awk '!/([[:digit:]]{2}:){2}[[:digit:]]{2}/ {print $1}' < file.txt
Run Code Online (Sandbox Code Playgroud)
awk
使用扩展的正则表达式,这是另一种方言。当心一些实现,包括mawk
仍然不支持{2}
间隔运算符或字符类。
在 中mawk
,你会这样做:
awk '!/[0-9][0-9]:[0-9][0-9]:[0-9][0-9]/ {print $1}' < file.txt
Run Code Online (Sandbox Code Playgroud)
这也应该适用于其他awk
实现,但请注意,对于某些[0-9]
可能会匹配 0123456789 以外的字符(非 ASCII 字符,因此您的输入可能不是问题)。
或者再次检查所有 5 个最后的字段是否与模式匹配:
awk '
{
for (i = 0; i < 5; i++)
if (!($(NF-i) ~ /^[0-9][0-9]:[0-9][0-9]:[0-9][0-9]$/)) {
print $1
next
}
}' < file.txt
Run Code Online (Sandbox Code Playgroud)