基于文件中第一个字段的唯一行数

时间:2012-12-11 14:57:34

标签: sed awk uniq

我试图根据第一个输出到文件的唯一行数 字段,输入行的外观如下:

Forms.js     /forms/Forms.js     http://www.gumby.com/test.htm   404
Forms.js     /forms/Forms1.js    http://www.gumby.com/test.htm   404
Forms.js     /forms/Forms2.js    http://www.gumby.com/test.htm   404
Interpret.js     /forms/Interpret1.js    http://www.gumby.com/test.htm   404    
Interpret.js     /forms/Interpret2.js    http://www.gumby.com/test.htm   404
Interpret.js     /forms/Interpret3.js    http://www.gumby.com/test.htm   404

对于这样的事情:

3    Forms.js    /forms/Forms.js     http://www.gumby.com.mx/test.htm 404
3    Interpret.js    /forms/Interpret.js    http://www.gumby.com.mx/test.htm  404

我一直在尝试sort和uniq的各种组合,但还没有尝试过。 我可以使用整行获得不同的线条,但我只想要第一个字段。 我目前正在使用cygwin。我不懂文字,但我 怀疑这是要走的路。任何人都有一个方便的解决方案?

6 个答案:

答案 0 :(得分:4)

此:

<infile awk '{ h[$1]++ } END { for(k in h) print h[k], k }'

会得到你:

3 Forms.js
3 Interpret.js

如果您还希望保持第一次使用:

awk '!h[$1] { g[$1]=$0 } { h[$1]++ } END { for(k in g) print h[k], g[k] }'

输出:

3 Forms.js /forms/Forms.js http://www.gumby.com/test.htm 404
3 Interpret.js /forms/Interpret1.js http://www.gumby.com/test.htm 404

使用GNU awk进行测试。

请注意,这不需要对输入进行排序。另请注意,结果是无序的。

答案 1 :(得分:2)

Awk是这方面的工具,但是如果你想要uniq聪明一点:

$ column -t file | uniq -w12 -c
      3 Forms.js      /forms/Forms.js       http://www.gumby.com/test.htm  404
      3 Interpret.js  /forms/Interpret1.js  http://www.gumby.com/test.htm  404

column -t对齐所有列,因此我们得到第一列的固定宽度。


如果column不可用,则 hack 是将第一列附加到awk行的末尾,然后使用uniq -c -f4来计算在最后一列上是唯一的,并再次使用awk来打印n-1字段。

$ awk '{print $0, $1}' file | uniq -c -f4 | awk '{$NF=""; NF--; print}'
3 Forms.js /forms/Forms.js http://www.gumby.com/test.htm 404
3 Interpret.js /forms/Interpret1.js http://www.gumby.com/test.htm 404

如果uniq -f-f4,4f1,1一样工作,那就太好了。


或者您可以使用rev来撤消该文件,以便uniq -c -f3可以完成,然后rev返回(但是如果你没有,那么你会得到最后的数量) t column您可能没有rev

$ rev file | uniq -c -f3 | rev
Forms.js /forms/Forms.js http://www.gumby.com/test.htm 404 3      
Interpret.js /forms/Interpret1.js http://www.gumby.com/test.htm 404 3

答案 2 :(得分:2)

$ awk '!c[$1]++{v[$1]=$0} END{for (i in c) print c[i],v[i]}' file
3 Forms.js     /forms/Forms.js     http://www.gumby.com/test.htm   404
3 Interpret.js     /forms/Interpret1.js    http://www.gumby.com/test.htm   404

以上使用'!array [$ n] ++'的常见awk惯用法来判断是否有一个键值($ n,其中n为$ 0或$ 1或$ 4,$ 5或......)。

答案 3 :(得分:1)

假设file.txt包含您的示例输入:

sort file.txt | awk -f counts.awk file

返回:

3:Forms.js     /forms/Forms.js     http://www.gumby.com/test.htm   404
3:Interpret.js     /forms/Interpret1.js    http://www.gumby.com/test.htm   404

awk脚本文件:

cat counts.awk

#  output format is:
#+ TimesFirstFieldIsRepeated:FirstMatchingLineContents

BEGIN {

  plmatch="";
  pline="";
  outline="";
  n=1;

 }

{

 if($1 != plmatch && NR != 1)
  {
   print n ":" outline;
   n=1;
   outline="";
  }

 if($1 == plmatch)
  {
   n+=1;
   if(outline == ""){
     outline=pline;
    }
  }

 plmatch=$1;
 pline=$0;

}

END {
  print n ":" outline;
 }

答案 4 :(得分:0)

我只是cut -f 1 | uniq -c。这不会给你整条线,但如果线条不同,打印任何线条都不会有太多意义。取决于你想要达到的目标。

答案 5 :(得分:0)

您可以使用cut计算第一个字段的数量,但是在此字段后要打印的内容是什么?

cat file | cut -d " " -f 1 | uniq -c