我正在尝试编写一个分析日志文件的脚本, 我想给用户提供输入模式的选项,然后打印在特定列(第五个)中匹配此模式的任何行 以下是终端的作品
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的帮助!!
答案 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问题,here和here以及其他地方。)
另一种选择可能是构建一个正则表达式,一次性搜索您感兴趣的所有单词。这样做的好处是可以使用一次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”,你可能会得到你不想要的结果。不过,你可以自己玩正则表达式。 :)
这会回答你的问题吗?