use*_*494 5 grep shell-script text-processing
有一个非常大的文本文件,其中包含两个以逗号分隔的值:
78414387,10033
78769989,12668
78771319,13677
78771340,13759
80367563,16336
81634533,10025
82878571,10196
110059366,10218
110059411,10812
110059451,10067
Run Code Online (Sandbox Code Playgroud)
我需要在看起来像这样的日志文件中搜索这些值:
- delivery-AMC_prod_product 231825855936862016-07-02 00:00:52 c.c.i.d.s.d.DeliveryTopologyFactory$$anon$1$$anon$2 [INFO] ack: uid=57773c737e3d80d7def296c7| id=278832702| version=28| timestamp=1467432051000
- delivery-AMC_prod_product 231825855936862016-07-02 00:00:52 c.c.i.d.s.d.DeliveryTopologyFactory$$anon$1$$anon$2 [INFO] ack: uid=57773c732f18c26fe604fd04| id=284057302| version=9| timestamp=1467432051000
- delivery-AMC_prod_product 231825855936862016-07-02 00:00:52 c.c.i.d.s.d.DeliveryTopologyFactory$$anon$1$$anon$2 [INFO] ack: uid=57773c747e3d80d7def296c8| id=357229| version=1151| timestamp=1467432052000
- delivery-AMC_prod_product 231825855936862016-07-02 00:00:52 c.c.i.d.s.d.DeliveryTopologyFactory$$anon$1$$anon$2 [INFO] ack: uid=57773c742f18c26fe604fd05| id=279832706| version=35| timestamp=1467432052000
- delivery-AMC_prod_product 231825855936862016-07-02 00:00:52 c.c.i.d.s.d.DeliveryTopologyFactory$$anon$1$$anon$2 [INFO] ack: uid=57773c744697ddb976cf5a95| id=354171| version=503| timestamp=1467432052000
- delivery-AMC_prod_product 231825855936862016-07-02 00:00:53 c.c.i.d.s.d.DeliveryTopologyFactory$$anon$1$$anon$2 [INFO] ack: uid=57773c754697ddb976cf5a96| id=355638| version=1287| timestamp=1467432053000
Run Code Online (Sandbox Code Playgroud)
我的脚本:
#!/bin/bash
COUNT=0
while IFS=',' read ID VERSION; do
VERSION=`echo $VERSION |col -bx`
if (grep "id=${ID}| version=$VERSION" worker-6715.log.2016-$1.log.* > /dev/null); then
let "COUNT++"
else
echo "$ID, $VERSION FAIL"
exit 2
fi
done < recon.txt
echo "All OK, $COUNT checked"
Run Code Online (Sandbox Code Playgroud)
您的瓶颈是recon.txt在 shell 中逐行读取文件。要获得失败的行,您可以预处理日志中的行,使其看起来像 中的行recon.txt,然后用于comm(1)查找设置的差异,可能如下所示:
comm -23 \
<(sort -u recon.txt) \
<(sed 's/.*| id=\([0-9]*\)| version=\([0-9]*\)|.*/\1,\2/' worker-6715.log.2016-$1.log.* | \
sort -u)
Run Code Online (Sandbox Code Playgroud)
这假设有一个可以处理<(...)构造的 shell。另请注意,结果中的行不保留 中行的顺序recon.txt。保持这个顺序会更困难(而且更慢)。
如果您还需要成功计数,则可以反其道而行之,进行预处理recon.txt,使其看起来像在日志中找到的内容,然后使用fgrep(1)或grep -F进行搜索。将区域设置设置为 还C可以在某些系统上显着加快速度。因此:
COUNT=$( \
sed 's/\([0-9]*\),\([0-9]*\)/| id=\1| version=\2|/' recon.txt | \
LC_ALL=C fgrep -f - worker-6715.log.2016-$1.log.* | \
wc -l )
Run Code Online (Sandbox Code Playgroud)
这假设recon.txt不包含重复项,并且每行在recon.txt所有日志中最多匹配一次。取消第一个限制将很困难。第二个可以通过仔细选择来解除comm(1)。