Unix 如何从列到行获取唯一值

Unix 如何从列到行获取唯一值,unix,awk,solaris,Unix,Awk,Solaris,我有一个输入文件,如: > 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列都有重

我有一个输入文件,如:

> 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列中找到唯一值,并在第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
我无法打印GNU awk第2列前面第1列的所有唯一值:

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追加一行。

对于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追加一行。

这里是另一行。它在[$2]后面附加以逗号分隔的$1值,但使用“匹配优先”检查该值是否已存在:

$ 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]。。。附加到数组 抹茶[$2],^ |,$1$|,?如果match找到匹配值,则为null :a[$2]==?:,$1或逗号(如果需要)和值
还有一个。它在[$2]后面附加以逗号分隔的$1值,但使用“匹配优先”检查该值是否已存在:

$ 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]。。。附加到数组 抹茶[$2],^ |,$1$|,?如果match找到匹配值,则为null :a[$2]==?:,$1或逗号(如果需要)和值 使用:

如果您坚持使用空格:

$ datamash --sort -t, -g 2 unique 1 < file | sed 's/,/ /'
281474976749447 16,17
281474976750348 16,17
使用:

如果您坚持使用空格:

$ datamash --sort -t, -g 2 unique 1 < file | sed 's/,/ /'
281474976749447 16,17
281474976750348 16,17
分拣辅助awk

sep用于延迟分隔符初始化,以跳过第一个分隔符。

排序辅助awk

sep用于延迟分隔符初始化,以跳过第一个分隔符。

使用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

因为这类似于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
使用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

因为这类似于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
下面是一个Perl:

以下是一个awk:

$ 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都使用关联数组,因此打印的顺序可能与文件中遇到的元素顺序不同。

以下是perl:

以下是一个awk:

$ 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都使用关联数组,因此打印的顺序可能与文件中元素的顺序不同。

使用编辑器中的{}按钮,或使用四个空格前置数据和代码。使用编辑器中的{}按钮,或使用四个空格前置数据和代码。Oooer。这是一个漂亮的节目。这是一个漂亮的程序。这是哪个awk?。。我得到语法错误$awk-F,“{a[$2][$1]+}”jeevan.txt awk:{a[$2][$1]+}awk:^syntaxerror@stack0114106您展示的内容中的++不是在他们的帖子中与Perl混淆的吗这是非法的。他们的代码为我运行。@stack0114106 Ok。。我建议删除所有这些评论?这是哪个awk?。。我得到语法错误$awk-F,“{a[$2][$1]+}”jeevan.txt awk:{a[$2][$1]+}awk:^syntaxerror@stack0114106您展示的内容中的++不是在他们的帖子中与Perl混淆的吗这是非法的。他们的代码为我运行。@stack0114106 Ok。。我建议删除所有这些注释?由于文件已排序,您可以比较prev和当前记录,并在读取行sort-t,-u-k2-k1,1 file | awk-F,{ifprev!=$2{x=NR>1?\n:;printf%s%s%s,x,$2,$1}else{printf,%s,$1}prev=$2}END{print}因为文件已排序,您可以比较prev和当前记录,并在读取sort-t,-u-k2-k1,1文件| awk-F'{ifprev!=$2{x=NR>1?\n:;printf%s%s,x,$2,$1}行时打印它们,否则{printf,%s,$1}prev=$2}结束{print}谢谢。。它帮助了我。很高兴它帮助了你。。请考虑接受答复。它帮助了我。很高兴它帮助了你。。请考虑接受答案。
$ 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