Bash:grep文件循环中的多个项目

时间:2014-04-28 12:18:13

标签: bash file shell scripting grep

我正在尝试编写一个Bash脚本,在一个循环中查找文件中多个项目的出现。这是我试图阅读的文件的一小部分:

112/14-13:21:18 - write(FD 1) = 82 bytes
112/14-13:21:18 - read(FD 0, 16384 bytes buffer) = 146 bytes
112/14-13:21:18 - unlink(/data/547/07/17/nmsa000000000005/archives/9589fecf-779b-4fc3-8bb3-4cd6b1932d19/ar16f8888285fb4989b817589b0219d08b) = 0
112/14-13:21:18 - __xstat64(1, /data/547/07/17/nmsa000000000005/archives/9589fecf-779b-4fc3-8bb3-4cd6b1932d19/ar16f8888285fb4989b817589b0219d08b, ...) = 0
112/14-13:21:18 - write(FD 1) = 86 bytes
112/14-13:21:18 - read(FD 0, 16384 bytes buffer) = 138 bytes

我想要的是,我可以显示有多少次“阅读”和“写入”以及花了多长时间。

目前我已经有了这个脚本:

#!/bin/bash

READ=0
WRITE=0

while read -r line || [[ -n $line ]]
do
    READ=$(grep -c 'read(')
    WRITE=$(grep -c 'write')
done < $1

echo "Read $READ times"
echo "Wrote $WRITE times"

但是我在一个小测试文件上收到了这个输出:

Read 20 times
Wrote 0 times

该脚本似乎不计算“写入”在输入文件中的次数。

我是Bash的新手,这是我的第一个剧本。谁能帮助或告诉我做错了什么?我如何实现脚本的时间部分? 此外,这个脚本可以优化,因为输入将非常大(+ 10GB文件)?

提前致谢!

编辑:额外的第二个数据

112/14-13:21:17 - __lxstat(1, /usr/share/pear/MDB2/Driver/Reverse/Common.php, ...) = 0
112/14-13:21:17 - open(/usr/share/pear/MDB2/Driver/Reverse/Common.php, 0) = FD 8
112/14-13:21:17 - close(FD 8) = 0
112/14-13:21:17 - __lxstat(1, /usr/local/lib/php/MDB2/Driver/Manager/pgsql.php, ...) = -1
112/14-13:21:17 - __lxstat(1, /usr/share/pear/MDB2/Driver/Manager/pgsql.php, ...) = 0
112/14-13:21:17 - __lxstat(1, /usr/share/pear/MDB2/Driver/Manager, ...) = 0
112/14-13:21:17 - open(/usr/share/pear/MDB2/Driver/Manager/pgsql.php, 0) = FD 8
112/14-13:21:17 - close(FD 8) = 0
112/14-13:21:17 - __lxstat(1, /usr/local/lib/php/MDB2/Driver/Manager/Common.php, ...) = -1
112/14-13:21:17 - __lxstat(1, /usr/share/pear/MDB2/Driver/Manager/Common.php, ...) = 0
112/14-13:21:17 - open(/usr/share/pear/MDB2/Driver/Manager/Common.php, 0) = FD 8
112/14-13:21:17 - close(FD 8) = 0
112/14-13:21:17 - __lxstat(1, /usr/local/lib/php/MDB2/Driver/Datatype/pgsql.php, ...) = -1
112/14-13:21:17 - __lxstat(1, /usr/share/pear/MDB2/Driver/Datatype/pgsql.php, ...) = 0
112/14-13:21:17 - __lxstat(1, /usr/share/pear/MDB2/Driver/Datatype, ...) = 0
112/14-13:21:17 - open(/usr/share/pear/MDB2/Driver/Datatype/pgsql.php, 0) = FD 8
112/14-13:21:17 - close(FD 8) = 0
112/14-13:21:17 - __lxstat(1, /usr/local/lib/php/MDB2/Driver/Datatype/Common.php, ...) = -1
112/14-13:21:17 - __lxstat(1, /usr/share/pear/MDB2/Driver/Datatype/Common.php, ...) = 0
112/14-13:21:17 - open(/usr/share/pear/MDB2/Driver/Datatype/Common.php, 0) = FD 8
112/14-13:21:17 - close(FD 8) = 0

4 个答案:

答案 0 :(得分:0)

为什么要循环?

此脚本可以正常工作:

#!/bin/bash
READ=$(grep -c 'read(' $1)
WRITE=$(grep -c 'write(' $1)
echo "Read $READ times"
echo "Wrote $WRITE times"

答案 1 :(得分:0)

在脚本中,将文件$1内的所有数据传递给while循环的stdin。您的初始read命令使用此数据的第一行,然后第一个grep命令使用剩余部分。这样就不会为第二个grep命令留下任何数据,因此它不会返回任何内容。作为副作用,如果文件的第一行包含read(,则grep不会对其进行计数,因为它已被read使用。因此可以改进你的脚本(类似于@ John的答案):

#!/bin/bash

READ=$(grep -c 'read(' "$1")
WRITE=$(grep -c 'write' "$1")
echo "Read ${READ:-0} times"
echo "Wrote ${WRITE:-0} times"

答案 2 :(得分:0)

也许尝试awk然后你只需要对文件进行一次传递,在此过程中你可以计算读写次数:

awk '/write\(/{w++;next}  /read\(/{r++;next}  END{print "Read: ",r, "Write: ",w}' file
Read:  2 Write:  2

这就是说...每当你在其中找到包含write(的行时,请增加w。每当您在其中找到包含read(的行时,请增加r。最后,请打印rw

如果您想要每秒的次数,可以使用:

awk 'FNR==1{r=0;w=0;lasttime=$1} $1!=lasttime{print lasttime,"Read: ",r, "Write: ",w;r=0;w=0;lasttime=$1} /write\(/{w++} /read\(/{r++}' file

基本上,每次第二次更改时,它都会输出读写次数。

答案 3 :(得分:0)

由于OP担心两次读取文件,所以可以这样做:

#!/bin/bash
R=0
W=0
while read -r line
do
        R=$((  $(grep -c 'read('  <<< "$line" )  + R ))
        W=$((  $(grep -c 'write(' <<< "$line" )  + W ))
done

printf "Read  %i times\n" $R
printf "Wrote %i times\n" $W

干杯,