Bash Uniq选项

问题描述 投票:1回答: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 for if的任何其他建议?

bash shell
2个回答
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

...或者你可以使用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
投票

不需要在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,那么最终可能会更加优雅和高效。

© www.soinside.com 2019 - 2024. All rights reserved.