我有一个ID数组,我想从日志文件中打印与数组中包含的任何值匹配的行。输入文件格式如下所示,必须匹配的数字以粗体显示。
2014-04-22 05:42:17 | SPPEventQueue_skl0.cpp(449)| 6 | CG | DEBUG |执行
2014-04-22 05:42:17 | abc.cpp(253)| 6 | USR | INFO | IN {Event :: removeEvent
2014-04-22 05:42:17 | cax.cpp(253)| 5 | USR | INFO | removeEvent number = 46574731
2014-04-22 05:42:17 | zaw.cpp(253)| 7 | USR | INFO |未找到任何活动。
2014-04-22 05:42:17 | asdf.cpp(253)| 3 | USR | INFO | OUT}活动
2014-04-22 05:42:17 | abcd.cpp(367)| 8 | CG | DEBUG | op Event :: Queue :: publish,publish
2014-04-22 05:42:17 | efgh.cpp(253)| 11 | USR | INFO | IN {Queue :: Event
2014-04-22 05:42:17 | xyz.cpp(253)| 4 | USR | INFO |在eventEumber的removeEvent中46574731
2014-04-22 05:42:17 | Event.cpp(503)| 6 | CG | DEBUG | op Queue :: Event :: removeEvent optimized,
2014-04-22 05:42:17 | form.cpp(253)| 1 | USR | INFO | IN {Queue :: EventQueue
2014-04-22 05:42:17 | service.cpp(1242)| 4 | P | DEBUG | commitObject:事务1285:5851已提交 2014-04-22 05:42:17 | form.cpp(253)| 6 | USR | INFO | removeEvent number = 46574731
以下代码有一个数组,用于比较每行中给定文件粗体值的每个元素。它读取文件的每一行,将上面粗体显示的值与数组的每个元素进行比较。如果找到匹配项,则该行存储在输出文件中。 它工作正常但需要很长时间才能读取超过10000行并与每个数组元素进行比较。
while read -r line; do
typeset CURTHREADID=echo "$line" | cut -d "|" -f 3
for index in ${THREADIDARR[@]}; do
if [ $CURTHREADID == $index ]; then
echo "$line" >> $OUTPUTFILE
break
fi
done
done < $INPUTFILE
我曾尝试使用AWK编写相同的代码,但它给了我一个错误,我不知道我在哪里失败。我需要帮助才能使用AWK编写相同内容,以便加快输出速度。这是我的尝试:
awk -v Thvar="$THREADIDARR" '
BEGIN{ command=cut -d "|" -f 3 }
{ CURTHREADID=getline | command
for(index in Thvar){
if(CURTHREADID == Thvar[index]){print;break;}
}}' $INPUTFILE
答案 0 :(得分:2)
你可以尝试:
awk -va="${THREADIDARR[*]}" '
{BEGIN {FS="|"; n=split(a,b," "); for (i=1; i<=n; i++) c[b[i]]=1}
$3 in c {print}' $INPUTFILE
答案 1 :(得分:2)
由于我对ksh
不太熟悉,以下是我使用awk
解决问题的方法:
awk -F'|' -v a="${THREADIDARR[*]}" '
BEGIN{
split(a,b," ")
for(i in b) c[b[i]]
}
$3 in c' $INPUTFILE
这将创建一个数组c,其键是输入数组的值。如果输入文件的第三列列在这些键中,则打印该行(默认操作)。
修改:这可能会使ksh
更快一些。我已删除了echo
和cut
部分:
#!/bin/ksh
while read line; do
IFS=\| read a b id c <<<$line
for i in ${THREADIDARR[*]}; do
if [ $i = $id ]; then
echo "$line" >> $OUTPUTFILE
break
fi
done
done < $INPUTFILE
修改:关于您的第二个问题,您可以将输入字段分隔符更改为:
或]
,这样就可以将其余代码更多或更少地保留相同的:
$INPUTFILE
:
20140320 00:08:23.846 INFO [WebContainer : 1] . anything line
20140320 00:08:23.846 INFO [WebContainer : 2] . anything line
20140320 00:08:23.846 INFO [WebContainer : 3] . anything line
20140320 00:08:23.846 INFO [WebContainer : 4] . anything line
20140320 00:08:23.846 INFO [WebContainer : 5] . anything line
代码:
THREADIDARR=(1 3)
awk -F": |]" -v a="${THREADIDARR[*]}" ' # two different field separators
BEGIN{
split(a,b," ")
for(i in b) c[b[i]]
}
$2 in c' $INPUTFILE # returns true (print) or false (don't print)
输出:
20140320 00:08:23.846 INFO [WebContainer : 1] . anything line
20140320 00:08:23.846 INFO [WebContainer : 3] . anything line