使用awk匹配日志文件中的列并打印整行

时间:2014-02-27 17:41:19

标签: regex bash awk

我正在尝试编写一个分析日志文件的脚本, 我想给用户提供输入模式的选项,然后打印在特定列(第五个)中匹配此模式的任何行 以下是终端的作品

awk ' $5=="acpid:" {print$0}' *filename*

确定如此以上我试图匹配“acpid:”这工作正常,但在脚本中我希望能够允许多个条目并搜索所有这些,问题是我搞乱了脚本中的变量就是我拥有的:

echo "enter any services you want details on, seperated by spaces"
read -a details
for i in ${details[@]}    
do 
        echo $i
        awk '$5 == "${i}" {print $0}' ${FILE}
done

如果我直接输入一个匹配的表达式而不是它的变量,那么我想我的问题就在这里,任何提示都会很棒

更新

所以我使用@ghoti建议的第二个选项(如下所示),因为它与我的日志文件稍微匹配得更好 但是,我没有任何运气与多个条目。香港专业教育学院添加了两行来说明结果我得到这些是echo $ i和echo“完成循环”放置它们应该告诉我当前循环的输入和我离开循环

    'read -a details
    re=""

    for i in "${details[@]}"; do
    re="$re${re:+|}$i"

     echo $i
     echo"finish loop"
    done

    awk -v re="$re" '$5 ~ re' "$FILE" `

当我单独读取“acpid”或“init”的输入时,匹配完美的结果,但是当输入为“acpid init”时,以下是输出

acpid init
    完成循环

我从中看到的是,读取将两个单词作为一个条目,然后awk正在搜索但不匹配它们(正如预期的那样)。那么为什么输入不被视为两个单独的条目我认为-a选项与read指定由空格分隔的单词将被放入数组的单独元素中。也许我还没有正确地声明数组?

更新更新

确定取消上面的更新,就像我这个傻瓜一样,我忘了那个id将IFS更改为\ n,早先在脚本中更改了它并且宾果游戏!!!

非常感谢@ghoti的帮助!!

1 个答案:

答案 0 :(得分:1)

有几种方法可以做你想做的事。

一个选项可能是为每个单词运行for循环,然后对awk应用不同的调用,并按顺序显示结果。例如,如果您在foo bar变量中输入$details,则可能会获得foo个匹配项列表,然后是bar个匹配项列表:

read -a details
for i in "${details[@]}"; do
  awk -v s="$i" '$5 == s' "$FILE"
done

这里的想法是我们使用awk的-v选项将每个单词都放入脚本中,而不是在引用的脚本中扩展变量。你应该阅读how bash deals with different kinds of quotes。 (关于该主题还有一些Stackoverflow问题,herehere以及其他地方。)

另一种选择可能是构建一个正则表达式,一次性搜索您感兴趣的所有单词。这样做的好处是可以使用一次awk来搜索$FILE

read -a details
re=""
for i in "${details[@]}"; do
  re="$re${re:+|}$i"
done
awk -v re="$re" '$5 ~ re' "$FILE"

结果将包含$FILE$FILE所有有趣的行,而不是按照您提供的字词排序。

请注意,这是一个相当基本的搜索,没有字边界,所以如果你搜索“foo bar babar”,你可能会得到你不想要的结果。不过,你可以自己玩正则表达式。 :)

这会回答你的问题吗?