我有一个输入文件,例如:
> cat test_mfd_1
16,281474976750348
17,281474976750348
16,281474976750348
17,281474976750348
16,281474976749447
17,281474976749447
16,281474976749447
17,281474976749447
我需要这样的输出:
281474976750348 16,17
281474976749447 16,17
第2列和第1列均具有重复的值。但是作为o / p,它应该在第2列中找到唯一值,并在行中打印所有相应的唯一值。
我正在使用awk,并且得到如下所示的o / p。
awk -F, '{a[$2]=$1;} END {for(i in a) print i" "a[i];}' test_mfd_1
281474976749447 17
281474976750348 17
我无法在第2列的前面打印第1列的所有唯一值
答案 0 :(得分:1)
对于GNU awk:
awk -F, '{a[$2][$1]} END {for(i in a) {printf i; first=1; for (j in a[i]) if (first) {printf " " j; first=0;} else printf "," j; print ""} }' test_mfd_1
#=> 281474976749447 16,17
#=> 281474976750348 16,17
改进您的尝试。
这个想法是使用二维数组和一个内部for
循环。
printf
不会打印换行符,因此请使用print ""
最后添加新行。
答案 1 :(得分:1)
这是另一个。它将以逗号分隔的$1
值附加到a[$2]
,但首先使用match()
来检查该值是否已经存在:
$ awk -F, '{
a[$2]=a[$2] (match(a[$2],"(^|,)" $1 "($|,)")?"":(a[$2]==""?"":",")$1)
}
END {
for(i in a)
print i,a[i]
} ' file
281474976749447 16,17
281474976750348 16,17
解释一下:
a[$2]=a[$2] (...
追加到数组match(a[$2],"(^|,)" $1 "($|,)")?""
找到匹配的值,match
为空:(a[$2]==""?"":",")$1)
或逗号(如果需要)和值答案 2 :(得分:1)
使用GNU Datamash
:
$ datamash --sort -t, -g 2 unique 1 < file
281474976749447,16,17
281474976750348,16,17
如果您坚持使用空格:
$ datamash --sort -t, -g 2 unique 1 < file | sed 's/,/ /'
281474976749447 16,17
281474976750348 16,17
答案 3 :(得分:1)
使用Perl
$ cat jeevan.txt
16,281474976750348
17,281474976750348
16,281474976750348
17,281474976750348
16,281474976749447
17,281474976749447
16,281474976749447
17,281474976749447
$ perl -F, -lane ' $kv{$F[1]}{$F[0]}++; END { while(my($x,$y) = each(%kv)) { print "$x ",join(",",keys %$y) } }' jeevan.txt
281474976749447 16,17
281474976750348 16,17
或
$ perl -F, -lane ' $kv{$F[1]}{$F[0]}++; END { print "$_ ",join(",",keys %{$kv{$_}}) for(keys %kv) } ' jeevan.txt
281474976749447 16,17
281474976750348 16,17
或
$ perl -F, -lane ' push @{$kv{$F[1]}},$F[0]; END { for(keys %kv) { %p=map{ $_ => 1} @{$kv{$_}} ; print "$_ ",join(",", keys %p) } } ' jeevan.txt
281474976749447 17,16
281474976750348 16,17
或
$ perl -F, -lane ' push @{$kv{$F[1]}},$F[0]; END { for my $a (keys %kv) { @p=grep{ !$s{$a}{$_}++ } @{$kv{$a}} ; print "$a ",join(",", @p) } } ' jeevan.txt
281474976749447 16,17
281474976750348 16,17
或
$ perl -F, -lane ' push @{$kv{$F[1]}},$F[0]; END { for my $a (keys %kv) { print "$a ",join(",", grep{ !$s{$a}{$_}++ } @{$kv{$a}}) } } ' jeevan.txt
281474976750348 16,17
281474976749447 16,17
由于它类似于SQL,因此您也可以使用sqlite
$ cat ./sqllite_unique.sh
#!/bin/sh
sqlite3 << EOF
create table t1(a,b);
.separator ','
.import $1 t1
select b|| ' ' || group_concat(distinct a) from t1 group by b;
EOF
$ ./sqllite_unique.sh jeevan.txt
281474976749447 16,17
281474976750348 16,17
答案 4 :(得分:1)
这里是Perl
:
$ perl -F, -lanE '$HoH{$F[1]}{$F[0]}++;
END{for (keys %HoH) {
say "$_ ", join(", ", keys %{$HoH{$_}}); }}' file
281474976749447 16, 17
281474976750348 17, 16
这是个可怕的事情
$ awk -F, '{a[$2][$1]}
END{ for (e in a){
s=""
for (x in a[e]) s=s?s ", " x:x
print e, s}}' file
281474976749447 16, 17
281474976750348 16, 17
注意:由于awk
和perl
都使用关联数组,因此打印顺序可能与文件中元素遇到的顺序不同。
答案 5 :(得分:0)
sort
辅助awk
$ sort -t, -u -k2 -k1,1 file |
awk -F, '{a[$2]=a[$2] sep[$2] $1; sep[$2]=FS} END{for(k in a) print k,a[k]}'
281474976749447 16,17
281474976750348 16,17
sep用于延迟分隔符的初始化,以跳过第一个。