我有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的任何其他建议吗?
答案 0 :(得分:1)
最简单的方法是首先进行计数。使用uniq
似乎没有简单的方法,但您可以使用Awk或循环来计算它。
合并所有数据(假设以空格分隔)
cat *.txt >all.txt
cat all.txt 2 hi 2 test 3 try 3 hi 5 test 3 try
重新计算
使用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 :(得分: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
,那么这可能会更加优雅和高效。