uniq
是一个工具,它允许一次过滤文件中的行,从而只显示唯一的行。uniq
支持指定两行什么时候是“等效的”,但是选项是有限的。
我正在寻找一个uniq
上的工具/扩展,它允许输入正则表达式。如果捕获的组对于两行是相同的,那么这两行就被认为是“等效的”。每个等价类只返回“第一个匹配”。
示例
file.dat
foo!bar!baz
!baz!quix
!bar!foobar
ID!baz!
使用grep -P '(!\w+!)' -o
,可以提取“唯一的部分”:
!bar!
!baz!
!bar!
!baz!
这意味着,第一行被认为与第三行“等价”,第二行与第四行相同。因此,只有第一和第二打印(第三和第四被忽略)。
然后uniq '(!\w+!)' < file.dat
应该返回:
foo!bar!baz
!baz!quix
发布于 2014-10-29 07:19:21
不是使用uniq
,而是使用gnu-awk,您可以获得所需的结果:
awk -v re='![[:alnum:]]+!' 'match($0, re, a) && !(a[0] in p) {p[a[0]]; print}' file
foo!bar!baz
!baz!quix
-v re=...
传递所需的正则表达式match
函数匹配每一行的正则表达式,并在[a]
中返回匹配的文本match
成功时,我们都会将匹配的文本存储在关联数组p
中并打印出来。uniq
支持的regex
函数。发布于 2014-10-29 07:20:52
下面是一个简单的Perl脚本,它将完成以下工作:
#!/usr/bin/env perl
use strict;
use warnings;
my $re = qr($ARGV[0]);
my %matches;
while(<STDIN>) {
next if $_ !~ $re;
print if !$matches{$1};
$matches{$1} = 1;
}
用法:
$ ./uniq.pl '(!\w+!)' < file.dat
foo!bar!baz
!baz!quix
在这里,我使用$1
来匹配第一个提取的组,但是您可以用$&
替换它来使用整个模式匹配。
此脚本将筛选出与正则表达式不匹配的行,但如果需要不同的行为,则可以对其进行调整。
发布于 2014-10-29 07:25:08
您只需使用grep
和sort
即可完成此操作。
DATAFILE=file.dat
for match in $(grep -P '(!\w+!)' -o "$DATAFILE" | sort -u); do
grep -m1 "$match" "$DATAFILE";
done
产出:
foo!bar!baz
!baz!quix
https://stackoverflow.com/questions/26633425
复制相似问题