Bash Uniq选项

时间:2018-01-02 00:49:36

标签: bash shell

我有20个文件。在每个文件中,我都列出了发生的单词及其频率。

示例:

 2 représentant 
 3 reproduire 
 2 réseau 
 1 rester 
 3 reste 
 1 résumer 

我使用此命令合并这20个文件

cat *.txt > tous.txt | sort | uniq -ci  | sort -k3

结果是例如:

2  2 représentant 
1  6 représentant 
5  3 reproduire
2  3 reproduire  
6  3 réseau
1  1 réseau
etc..

但我想要的是让它计算每个单词的出现次数而不用多次写入。我想要的是:

8 representant
6 reproduire
4 réseau
... 

我可以用awk做到这一点:

awk '{tab[$2]+=$1} END {for(i in tab){printf("%7d %s\n", tab[i], i) | "sort -k2"}}' ~/Bureau/Projet/data/dico/*.dico.forme.txt > ~/Bureau/Projet/data/input/black.txt

使用ex for if的任何其他建议吗?

2 个答案:

答案 0 :(得分:1)

最简单的方法是首先进行计数。使用uniq似乎没有简单的方法,但您可以使用Awk或循环来计算它。

  1. 合并所有数据(假设以空格分隔)

    cat *.txt >all.txt
    
    cat all.txt  
    2 hi  
    2 test  
    3 try  
    3 hi  
    5 test  
    3 try
    
  2. 重新计算

    使用Awk:

    sort -k2,2 all.txt | awk '{a[$2] += $1} END{for (i in a) print a[i],i}'
    

    输出:

      5 hi  
      7 test  
      6 try
    
  3. ...或者你可以使用while循环(效率较低):

    while read -r a; do
        echo "$(grep -w "$a" all.txt|cut -d ' ' -f1|paste -sd+|bc)" "$a"
    done< <(cut -d ' ' -f2 all.txt|sort -u)
    

    或反转uniq -c所做的事情:

    while read -r a b; do
        yes "$b" |head -n "$a"
    done <all.txt | sort| uniq -c
    

答案 1 :(得分:1)

不需要在tous.txt中存储中间结果,也不需要将整个数组保存在内存中,尽管这是一个小的效率黑客,除非你的数据集是大。

sort -k2,2 *.txt |
awk 'NR>1 && $2 != prev { print sum, prev; sum = 0 }
    { prev = $2; sum += $1 }
    END { print sum, prev }'

注意END块如何重复(部分)主流。 (缺少最后一个输出行是这种常规方法的常见错误。)

正如其他人已经建议的那样,如果您可以避免使用*.txt文件并直接使用整个原始输入sort | uniq -c,那么这可能会更加优雅和高效。

相关问题