Bash Uniq选项

Bash Uniq选项,bash,shell,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

我有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 if?

还有其他建议吗?

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

  • 合并所有数据(假设空间分开)

  • 再数一数

    使用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
    
  • 。。。或者,您可以使用
    while
    循环(效率较低)执行此操作:


    不需要将中间结果存储在
    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
    文件,直接使用整个原始输入进行
    排序| uniq-c
    ,这可能会更加优雅和高效。

    使用简单的排序和uniq管道无法实现这一点。仅仅使用这些工具来获取预先存在的计数并求和是没有好方法的。您可以使用更复杂的Bash脚本来完成,但Awk是更简单且可能是最好的方法。根据您的描述,单词出现总数不应该是:
    10 représentant
    21 reproduire
    19 réseau
    ,也就是说,每行中列出的单词出现总数乘以这些计数出现的次数,再加上同一单词的任何其他此类计数?é将不计算在内,因为请向我们显示您使用的确切命令。您问题中的命令:
    cat*.txt>tous.txt | sort | uniq-ci | sort-k3
    不会执行您所说的操作。
    cat*.txt
    的输出被写入
    tous.txt
    ,并且将不能作为
    sort
    的输入。我同意“首先不要进行计数”,但其余的都很糟糕。恐怕不行。您和您仍然不必要地使用临时文件,并且事后未能清理;但更一般地说,OP的Awk脚本在有效解决问题方面已经做得更好了。您的Awk重构有点改进,但它失去了排序顺序。在任何情况下,我都会犹豫是否删除我的否决票,只要您的shell脚本甚至没有在每次迭代中通过读取整个文件来
    grep
    ,这是非常低效的。使用
    echo
    和backticks也会引起一些奇怪的嗅觉感觉,虽然从技术上讲这不是一个问题,但我不情愿地取消了我对你所付出的所有努力的否决票,但实际上,这个答案的TLDR是,“我没有比OP的Awk脚本更好的解决方案。”。请注意,
    *.txt
    将与
    tous.txt
    匹配,因此请在运行此操作之前删除它。
      5 hi  
      7 test  
      6 try
    
    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)
    
    while read -r a b; do
        yes "$b" |head -n "$a"
    done <all.txt | sort| uniq -c
    
    sort -k2,2 *.txt |
    awk 'NR>1 && $2 != prev { print sum, prev; sum = 0 }
        { prev = $2; sum += $1 }
        END { print sum, prev }'