【问题标题】:Can sort | uniq or sort | awk count repeated values from one column?可以排序 | uniq 或排序 | awk 计算一列中的重复值?
【发布时间】:2013-05-23 22:33:31
【问题描述】:

使用以下数据:

$cat p1.csv
R,3
R,4
S,1
S,2
S,3
R,2
T,4
R,3
ST,4
RST,2
RSTR,4

基于第 2 列的第一次排序:

$cat p1.csv | sort -t "," -k2
S,1
R,2
RST,2
S,2
R,3
R,3
S,3
R,4
RSTR,4
ST,4
T,4

我想从第二列计算 1、2、3 和 4 的数量。类似于 $cat p1.csv |排序 -t "," -k2 | uniq -f2 -c .....uniq 可以应用于一列吗? -f2 没有正确地将 uniq 应用于正确的字段。输出应采用第二列中唯一值的第一个实例并计算它们的数量。因此,数据必须首先按第二列排序。正确的输出如下所示:

1 S,1
3 R,2
3 R,3
4 R,4

建议?

【问题讨论】:

  • 我确信可以使用awk 完成。您可能会做一些更麻烦的事情,并且确实需要使用 uniqsortgrep -c 的脚本,否则效率会降低。
  • 我不明白你的输出。 ST, T, RST, RSTR 在哪里?输出的第一列是什么?
  • 请注意,以下每一行都是出现在第二列中的数字的第一个实例:S,1 R,2 R,3 R,4。该操作应在第一个实例中停止第二列中的 uniq 值并计算出现了多少个 uniq 数字。所以@Kent,回答你的问题,ST、T、RST、RSTR 不被认为是 uniq。只有第二列中的值是唯一的。

标签: sorting awk uniq


【解决方案1】:

您的问题不太清楚,所以我只是将您的输出逆向工程到您的输入(假设您的输出中有错字,因为您提到从第 2 列计算 1、2 和 3 的数量并显示 2 R,2) .您可能需要更好地解释您的问题 -

sort -t "," -k2 < p1.csv |   
awk -F, '!z[$2]++{ a[$2]=$0; } END {for (i in a) print z[i], a[i]}' |  
sort -k1

说明:

 - !z[$2]++ removes the duplicates based on column 2 as awk progresses thru 
   each line. 
 - a[$2]=$0 stores the non-duplicates lines in an array
 - END {..} looks at all the keys in array and pulls up values. For array a 
   it pulls up the first line it sees with unique column 2 (as your desired 
   output). For array z it pulls up number of lines seen with same column 2.

测试:

[jaypal:~/temp] cat file
R,3
R,4
S,1
S,2
S,3
R,2
T,4
R,3
ST,4
RST,2
RSTR,4

[jaypal:~/temp] sort -t "," -k2 < t |   
awk -F, '!z[$2]++{ a[$2]=$0; } END {for (i in a) print z[i], a[i]}' |  
sort -k1
1 S,1
3 R,2
3 R,3
4 R,4

使用 -u 选项排序

要根据列查找唯一条目,您可以尝试使用 -u 选项进行排序(但它不会为您提供计数)。

来自man 页面:

-u, --unique
              with -c, check for strict ordering; 
              without -c, output only the first of an equal run

你可以试试这样的 -

sort -t, -k2 p1.csv | sort -u -t, -k2

使用 Uniq

我不确定 Uniq 是否可以在由空格以外的分隔符分隔的列上执行。至少在我的mac上没有。这是手册页参考

-f num  Ignore the first num fields in each input line when doing comparisons.  
        A field is a string of non-blank characters separated
        from adjacent fields by blanks.  Field numbers are one based, 
        i.e., the first field is field one.

因此,如果您可以删除 , 分隔符并运行以下命令,您应该会得到您想要的结果。

sort -k2 test | uniq -c -f1

测试:

[jaypal:~/temp] cat test
R 3
R 4
S 1
S 2
S 3
R 2
T 4
R 3
ST 4
RST 2
RSTR 4

[jaypal:~/temp] sort -k2 test | uniq -c -f1
   1 S 1
   3 R 2
   3 R 3
   4 R 4

【讨论】:

  • $cat p1.csv |排序 -t "," -k2 | uniq -f2 -c .....uniq 可以应用于一列吗? -f2 没有正确地将 uniq 应用于正确的字段。
  • @Jaypal:如果你有时间,你能解释一下你的 awk 函数的部分吗??
  • @simplyclimb 为您的第一个问题添加了解释和答案。希望对您有所帮助。
【解决方案2】:

我刚刚遇到了一个有趣的案例,即数据集中的重复值很容易解决,我只是想把这个案例提供给任何可能感兴趣的人。

我正在向数据集添加两个附加项 (*):

$cat p1.space
  R 3
  R 4
  S 1
  S 2
  S 3
  R 2
  T 4
  R 3
  ST 4
  RST 2
  RSTR 4
  R* 5
  R* 5

新值包括一个重复的条目 R* 5。按第二列排序,我们看到以下新值:

$sort -k2 p1.space
  S 1
  R 2
  RST 2
  S 2
  R 3
  R 3
  S 3
  R 4
  RSTR 4
  ST 4
  T 4
  R* 5
  R* 5

注意重复项 (R* 5) 如何计为两个条目:

$sort -k2 p1.space | uniq -f1 -c
  1 S 1
  3 R 2
  3 R 3
  4 R 4
  2 R* 5

要保存 uniq 行的计数,我们必须在计算 uniq 行数之前对数据集进行 uniq:

$sort -k2 p1.space | uniq | uniq -f1 -c
  1 S 1
  3 R 2
  2 R 3
  4 R 4
  1 R* 5

我希望这对可能有类似计数要求的任何人有所帮助。祝你好运!谢谢@Jaypal。

【讨论】:

    猜你喜欢
    • 2019-06-12
    • 2011-02-24
    • 2015-10-10
    • 2015-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-20
    • 2016-06-02
    相关资源
    最近更新 更多