2

我正在尝试根据第一个字段计算输出到文件的唯一行数,其中输入行如下所示:

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。我不识字,但我怀疑这是要走的路。任何人有一个方便的解决方案?

4

6 回答 6

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 测试。

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

于 2012-12-11T15:12:08.790 回答
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对齐所有列,因此我们得到第一列的固定宽度。


或者,如果不可用,则hack是将第一列附加到行尾,然后用于计算最后一列的唯一性并再次用于打印字段。columnawkuniq -c -f4awkn-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,4or一样工作会很好f1,1


或者您可以使用rev来反转文件,以便uniq -c -f3可以完成然后rev返回(但是最后会得到计数,如果没有,则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
于 2012-12-11T15:04:37.103 回答
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 或 ...)是否曾见过。

于 2012-12-12T16:57:38.883 回答
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;
 }
于 2012-12-11T15:59:29.963 回答
0

我只是cut -f 1 | uniq -c。这不会给你整行,但如果行不同,打印任何行无论如何都没有太大意义。取决于你想要达到什么。

于 2012-12-11T15:11:39.490 回答
0

您可以计算第一个字段的数量,cut但您想在该字段之后打印什么?

cat file | cut -d " " -f 1 | uniq -c
于 2012-12-11T15:11:49.290 回答