如何总结我文件中的数字?

时间:2016-02-24 10:53:32

标签: bash shell unix grep

我有一个文件夹my_folder,其中包含800多个文件myfile_*,其中*是每个文件的唯一ID。在我的文件中,我基本上有各种重复的字段,但我感兴趣的是<rating>字段。此字段的行如下所示:<rating>n其中n是评分。这些行每隔14行出现一次,从第10行(10 + 14i)开始,到文件结束时结束。我的工作是编写一个脚本myscript.sh,以总结我文件夹中每个文件的所有n值,然后从最高到最小排序。输出结果如下

myfile_1234 5112
myfile_5214 2134
myfile_6124 1233
...

其中数字后缀是每个文件的n的总和。我的文件长度差异很大,从20个字段到2500个字段。我将如何做到这一点?我想我将使用某种形式的grep命令来查找<rating>的出现,然后总结出现后的数字,或者可以使用每10 + 14i行出现这一行的事实,从10开始。感谢您的时间,非常感谢任何建议。

输入文件:

<Overall Rating>2.5
<Avg. Price>$155
<URL>

<Author>Jeter5
<Content>I hope we're not disappointed! We enjoyed New Orleans...
<Date>Dec 19, 2008
<No. Reader>-1
<No. Helpful>-1
<rating>4
<Value>-1
<Rooms>3
<Location>5
<Cleanliness>3
<Check in / front desk>5
<Service>5
<Business service>5

<Author>...
repeat fields again...

脚本必须在命令行中将文件夹名称作为参数,例如./myscript.sh my_folder

2 个答案:

答案 0 :(得分:2)

你可以使用awk而不关心起跑线

如果我很好理解,如果您输入以下命令:

grep rating fileName.txt 

你会有类似的东西(我已经创建了一个示例输入文件):

grep "<rating>" myfile_12345
<rating>7                                                                                                                                                                                                                                               
<rating>1
<rating>2

您可以使用此awk

awk -F"<rating>" 'BEGIN{sum=0}{sum+=$2}END{print sum}' myfile_12345

输出中:

10

然后您可以在for循环

中使用它
for file in $(find . -name "myfile_*")
do
  printf "%s $file "
  awk -F"<rating>" 'BEGIN{sum=0}{sum+=$2}END{printf " %s\t\n", sum}' $file
done

输出:

./myfile_12345  10                                                                                                                                                                                                                                     
./myfile_17676  19                                                                                                                                                                                                                                     
./myfile_9898  24 

最好的问候

克劳迪奥

答案 1 :(得分:2)

这是我的解决方案:

#/bin/bash
dir=$1

grep -P -o '(?<=<rating>).*' $dir/* |awk -F: '{A[$1]+=$2;next}END{for(i in A){print i,A[i]}}'|sort -n -k2

看起来最终的排序并不需要,所以你可以删除它。