鉴于此数据
A 1.20 GBP 1.2 GBP
B 1.2 GBP 1.20 GBP
C 01 GBP 1 GBP
D 1 GBP 01 GBP
E 1.0 GBP 1 GBP
F 1 GBP 1.0 GBP
G 2.10 GBP 3.2 GBP
H 4.1 GBP 3.20 GBP
I 04 GBP 3 GBP
J 4 GBP 03 GBP
K 4.0 GBP 3 GBP
L 4 GBP 3.0 GBP
我必须找到值不同的行(使用grep -P)。
每个号码之间只有一个空格,3.2 = 03.20, 3.0 = 3
我试过这个
grep -P '([1-9][0-9]*(?:\.[0-9]*[1-9])?)(\.?0*) ([A-Z]{3}) 0*(?!\1).* \3' filename
不幸的是它似乎没有正常工作。我实际上并不确定否定前瞻。
我知道有很多更好的方法可以达到这个结果。
但是我是学生,这是我必须用正则表达式使用grep做的练习。
我尝试过的工作直到它得到更棘手的测试,所以如果你能提供帮助,那就告诉我我做错了什么。
结果应为:
G 2.10 GBP 3.2 GBP
H 4.1 GBP 3.20 GBP
I 04 GBP 3 GBP
J 4 GBP 03 GBP
K 4.0 GBP 3 GBP
L 4 GBP 3.0 GBP
我已经测试了我的解决方案,它还会返回:
A 1.20 GBP 1.2 GBP
B 1.2 GBP 1.20 GBP
D 1 GBP 01 GBP
我还检查了https://regex101.com/中的正则表达式。结果令人惊讶,因为对于A行和B行,正则表达式只占用了句点后的数字。检查一下,知道我在说什么。
对于那些讲述grep -v的人的另一个编辑: 我没有提出整个运动。在每个数字之后,还有其他东西必须相同,所以当我使用grep -v时,它仍然不起作用而且它已知原因。必须有一个否定。
答案 0 :(得分:2)
使用awk
非常简单,为什么要这么麻烦?
$ awk '$2!=$4' input.txt
结果:
G 2.10 GBP 3.2 GBP
H 4.1 GBP 3.20 GBP
I 04 GBP 3 GBP
J 4 GBP 03 GBP
K 4.0 GBP 3 GBP
L 4 GBP 3.0 GBP
awk
会自动将值处理到float
中,因此比较很容易(即使浮动比较有时很危险,在您的情况下也很有效)
答案 1 :(得分:1)
您可以使用此位复杂正则表达式执行此任务:
grep -P '\h+0*(?:(?:(\d+)\.?0*\h+0*\1\.?0*|(\d+\.\d*[1-9])0*\h+\g{2}0*)(*SKIP)(*F)|.*)$' file
G 2.10 3.2
H 4.1 3.20
I 04 3
J 4 03
K 4.0 3
L 4 3.0
PCRE动词(*SKIP)(*F)
用于在交替中跳过匹配。
另外,你也可以使用这个负前瞻性正则表达式:
grep -P '^\S+\h+(?!0*(?:(\d+)\.?0*\h+0*\1\.?0*|(\d+\.\d*[1-9])0*\h+\g{2}0*)$)' file
G 2.10 3.2
H 4.1 3.20
I 04 3
J 4 03
K 4.0 3
L 4 3.0
编辑2 :要包含货币以及使用:
grep -P '^\S+\h+(?!0*(?:(\d+)\.?0*\h+([A-Z]+)\h+0*\1\.?0*\h+\2|(\d+\.\d*[1-9])0*\h+([A-Z]+)\h+\g{3}0*\h+\4)$)' file
G 2.10 GBP 3.2 GBP
H 4.1 GBP 3.20 GBP
I 04 GBP 3 GBP
J 4 GBP 03 GBP
K 4.0 GBP 3 GBP
L 4 GBP 3.0 GBP
答案 2 :(得分:0)
可能有一个更简单的解决方案。这是相当丑陋的,但它完成了工作
grep -v -P '\s+0*(\d+(?:\.\d*[1-9])?)[.0]*\s+0*\1[.0]*\b' filename