5

我需要重新排序这个(制表符分隔的)数据的列:

   1 cat    plays
   1 dog    eats
   1 horse  runs
   1 red    dog
   1 the    cat
   1 the    cat

所以打印如下:

cat plays   1
dog eats    1
horse   runs    1
red dog 1
the cat 2

我努力了:

sort [input] | uniq -c | awk '{print $2 "\t" $3 "\t" $1}' > [output]

结果是:

1   cat 1
1   dog 1
1   horse   1
1   red 1
2   the 1

谁能给我一些关于出了什么问题的见解?谢谢你。

4

4 回答 4

8

由于的输出cat input | sort | uniq -c是:

   1    1 cat    plays
   1    1 dog    eats
   1    1 horse  runs
   1    1 red    dog
   2    1 the    cat

你需要类似的东西:

cat input | sort | uniq -c | awk '{print $3 "\t" $4 "\t" $1}'

我们还可以在 awk 中指明输出字段分隔符:

cat input | sort | uniq -c | awk -v OFS="\t" '{print $3,$4,$1}'
于 2013-09-22T17:10:23.840 回答
3

uniq -c添加一个额外的列。这应该给你你想要的输出:

$ sort file | uniq -c | awk '{print $3 "\t" $4 "\t" $1}'
cat     plays   1
dog     eats    1
horse   runs    1
red     dog     1
the     cat     2
于 2013-09-22T17:10:33.047 回答
2

如果您有 GNU awk (gawk),则只能使用它及其功能asorti()

#!/usr/bin/env gawk -f
{
    a[$2 "\t" $3]++
}
END {
    asorti(a, b)
    for (i = 1; i in b; ++i) print b[i] "\t" a[b[i]]
}

一条线:

gawk '{++a[$2"\t"$3]}END{asorti(a,b);for(i=1;i in b;++i)print b[i]"\t"a[b[i]]}' file

输出:

cat plays   1
dog eats    1
horse   runs    1
red dog 1
the cat 2

更新:要保留原始顺序而不进行排序,请使用:

#!/usr/bin/awk -f
!a[$2 "\t" $3]++ {
    b[++i] = $2 "\t" $3
}
END {
    for (j = 1; j <= i; ++j) print b[j] "\t" a[b[j]]
}

或者

awk '!a[$2"\t"$3]++{b[++i]=$2"\t"$3}END{for(j=1;j<=i;++j)print b[j]"\t"a[b[j]]}' file

这次任何 awk 版本都将与它兼容。

这次输出应该是相同的,因为默认情况下输入已经排序。

于 2013-09-22T17:27:02.807 回答
2

awksort:_

$ awk '{a[$2 OFS $3]++}END{for(k in a)print k,a[k]}' OFS='\t' file | sort -nk3 
cat     plays   1
dog     eats    1
horse   runs    1
red     dog     1
the     cat     2
于 2013-09-22T17:19:28.743 回答