Arrays 逐行读取文件并与shell数组元素进行比较:ksh

Arrays 逐行读取文件并与shell数组元素进行比较:ksh,arrays,awk,Arrays,Awk,我有一个ID数组,我想打印日志文件中与数组中包含的任何值匹配的行。输入文件格式如下所示,必须匹配的数字以粗体显示 2014-04-22 05:42:17 | SPPEventQueue|u skl0.cpp(449)|6| CG | DEBUG | Executing 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

我有一个ID数组,我想打印日志文件中与数组中包含的任何值匹配的行。输入文件格式如下所示,必须匹配的数字以粗体显示

2014-04-22 05:42:17 | SPPEventQueue|u skl0.cpp(449)|6| CG | DEBUG | Executing
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,直接发布
2014-04-22 05:42:17 | efgh.cpp(253)|11| USR | INFO |{Queue::Event
2014-04-22 05:42:17 | xyz.cpp(253)|4| USR |信息|用于事件编号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 |{Queue::EventQueue
2014-04-22 05:42:17 | service.cpp(1242)|4| P | DEBUG | committobject:事务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 -va="${THREADIDARR[*]}" '
 {BEGIN {FS="|"; n=split(a,b," "); for (i=1; i<=n; i++) c[b[i]]=1}
 $3 in c {print}' $INPUTFILE
awk-va=“${THREADIDARR[*]}”

{BEGIN{FS=“|”;n=split(a,b)”;for(i=1;i由于我不太熟悉
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
代码:

输出:

20140320 00:08:23.846 INFO [WebContainer : 1] . anything line
20140320 00:08:23.846 INFO [WebContainer : 3] . anything line

如果您可以发布错误,则很有用我有另一个文件,但行格式不同,但需要对数组和每行执行相同的操作:在我将行格式设置为
2014-04-22 05:42:17 | SPPEventQueue_skl0.cpp(449)| 6 | CG | DEBUG |执行
并编码为
“$line”| cut d”|-f 3
它与以下代码一起工作。我有另一个文件格式,如下所示
20140320 00:08:23.846信息[WebContainer:*84**]。任何行
我都尝试过for循环和数组,代码如下
echo“$line”| cut-d”“-f 6 | cut-d”“”-f1
任何人都可以帮助我。因此需要在awk循环中提供嵌套拆分,或者可以用另一种方式实现编码的
echo“$line”| cut-d”“-f6 | cut-d”]”-f 1
。有人能帮我吗。我已经添加了我的答案,以便它适用于您的第二种类型的文件。一般来说,如果您还有其他问题,您应该单独问。如果您的问题解决了,请不要忘记接受答案。+1完全正确。我喜欢我们甚至都使用相同的变量名!@TomFenech谢谢:)我也不知道kshell,但我认为解决方案并不依赖于此。谢谢Tom,在第二个答案中,只有最后一个数组元素与行比较并显示。假设在数组中我有(4 11和7)然后只显示带有7的行。我认为这并不是从带有行的数组值和解析中比较4和11。感谢Håkon Hægland和Tom Fenech,这两种逻辑都工作正常。但如果在匹配ThreadiD后立即得到任何异常,那么这些行也需要显示假设匹配的线程ID为1 and 3,则只应显示第3行之后的异常。不需要显示线程Id 5之后的异常,这两个文件都需要帮助。
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