在shell脚本中记录处理

时间:2015-02-03 03:50:33

标签: shell

我正在编写一个shell脚本来处理目录中的多个gz文件。每个文件包含多个由-------------分隔的记录

A = 1

B = 2

C =随机= 1

EOE


A = 2

B = 2

C =随机= 1,伪= 2

EOE


现在我的问题是我需要浏览所有文件,并且文件中的每个记录确定A的值,然后它的1然后进一步处理该记录,否则忽略记录并移动到下一个。 如果A = 1  然后需要确定记录是否具有dummy = 2的值,如果它存在则递增计数器并最终在屏幕上打印计数器。所以在上面的例子中我应该打印1。

我是linux世界的新手,所以我开始使用

for(file in query*)
 do
    record = //not sure how to get individual record and proceed futher

有人可以解释如何获取个人记录,然后使用grep确定文本并返回计数吗?

1 个答案:

答案 0 :(得分:0)

假设这是我们的gzip压缩文件:

$ zcat file.gz
A=1
B=2
C=random=1
-----------
A=2
B=2
C=random=1,dummy=2
------------
A=1
B=2
C=random=1,dummy=2
-----------

如果我们想要计算单条记录同时包含A=1dummy=2的次数,请使用:

$ zcat file.gz | awk -v RS="-----------\n" '/A=2[ ,\n]/ && /dummy=2[ ,\n]/{count++} END{print "Final counter value=",count}'
Final counter value= 1

如何运作

  • -v RS="-----------\n"

    awk将文件分隔为记录。在这里,我们告诉它使用一系列破折号作为记录分隔符。

  • '/ A = 2 [,\ n] /&& / dummy = 2 [,\ n] / {count ++}`

    每次awk遇到新记录时都会执行此语句。该语句由两部分组成:条件和命令。这两个条件是记录包含A=1dummy=2。如果满足这些条件,则执行命令,该命令递增称为count的计数器。

    更准确地说,/A=2[ ,\n]/要求记录包含A=2后跟空格,逗号或换行符。这可以防止A=20匹配。

  • END{print "Final counter value=",count}

    这是在awk完成文件后执行的。这只是打印出结果。

一次处理多个文件

如果目录中有多个.gz个文件,我们想要获取每个文件的计数:

for f in *.gz
do
    echo " $f: count=$(zcat "$f" | awk -v RS="-----------\n" '/A=2[ ,\n]/ && /dummy=2[ ,\n]/{count++} END{print count}')"
done

在多个文件中查找总计

获取当前目录中所有.gz个文件的计数:

zcat *.gz | awk -v RS="-----------\n" '/A=2[ ,\n]/ && /dummy=2[ ,\n]/{count++} END{print "Final counter value=",count}'

使用多个计数器

假设我们还想计算没有dummy=2的记录数(我们将other):

$ zcat file.gz | awk -v RS="-----------\n" '/A=2[ ,\n]/ && /dummy=2[ ,\n]/{count++} !/dummy=2[ ,\n]/{other++} END{print "Final counter value=",count, "; other=", other}'
Final counter value= 1 ; other= 1