首页 > 解决方案 > “awk”未按预期处理 shell 变量

问题描述

我正在从日志文件中过滤特定文本。这里的问题是 awk 没有处理 shell 变量。但在文件名上工作正常。每当有新日志出现时,我都会在循环中使用“new_log=tail -n5 alerts.log”将日志文件中的新日志条目存储在 shell 变量中,然后,

Level_no=`awk '{FS="Rule: "}{print $2}' "$new_log" | sed '/^$/d' | awk '{FS=" "}{print $3}' | sed 's/)//g'

输出:

awk: fatal: cannot open file `** Alert 1564460779.1380: mail  - ossec,syscheck
* New Log starts from ** Alert 1564460779.1380: mail  - ossec,syscheck *`

上面提到的命令在我使用文件名而不是 shell 变量在终端中运行时效果很好,如下所示:

awk '{FS="Rule: "}{print $2}' logs_mining | sed '/^$/d' | awk '{FS=" "}{print $3}' | sed 's/)//g'

但是如果我将新的日志条目存储在另一个文件中并从那里处理,它的性能问题。

所以我研究得越来越多,开始了解 awk 变量……这是我的 shell 脚本……

Level_no=`awk -v var="$new_log" '{FS="Rule: "}{print $2}' var | sed '/^$/d' | awk '{FS=" "}{print $3}' | sed 's/)//g'

然后输出说

awk: fatal: cannot open file `var' for reading (No such file or directory)

实际结果应该是成功执行 awk 脚本。

标签: linuxbashshellawkscripting

解决方案


如果new_log包含要处理的数据,而不是文件名,则需要将其通过管道传输到awk. 您可以使用此处的字符串来执行此操作。

Level_no=`awk '{FS="Rule: "}{print $2}' <<<"$new_log" | sed '/^$/d' | awk '{FS=" "}{print $3}' | sed 's/)//g'`

也没有必要将输出通过管道传输到sed另一个awk,您可以在第一个脚本中完成所有操作。

Level_no=$(awk -F'Rule: ' '$2 != "" {split($2, a, " "); gsub(/)/, "", a[3]); print a[3]}' <<<"$new_log")

但是,您可能不需要该变量,只需将命令的输出通过管道传输到 awk:

Level_no=$(tail -n5 alerts.log | awk -F'Rule: ' '$2 != "" {split($2, a, " "); gsub(/)/, "", a[3]); print a[3]}')

推荐阅读