在 awk 中将变量传递给范围模式

在 awk 中将变量传递给范围模式

我正在尝试在 awk 中使用范围模式:

grep -a volume somefile | awk '/^Apr 25 23:44:04*/,/^Apr 26 12:44:01*/ {print}'

这工作正常,但是当我尝试通过将日期和时间放入变量并执行来执行它时,它似乎不起作用:

time1="Apr 25 23:44:04"
time2="Apr 26 12:44:01"
grep -a volume somefile | awk '/^"$time1"*/,/^"$time2"*/ {print}'

答案1

因为 shell 变量位于单引号字符串内,所以它们不会被扩展。单引号字符串内部包含双引号并不重要,它仍然是单引号字符串。

改用:

grep -a volume somefile | awk "/^$time1/,/^$time2/ {print}"

事实上,既然print默认动作,可以将其简化为:

grep -a volume somefile | awk "/^$time1/,/^$time2/"

您确实需要小心这种方法。您必须确保既不time1也不time2包含无意的 awk-active 字符。

更安全的方法是将 shell 变量传输到 awk 变量:

grep -a volume somefile | awk -v t1="$time1" -v t2="$time2" '($0~"^"t1),($0~"^"t2)'

请注意,即使采用这种更安全的方法,正如 Gilles 在评论中指出的那样,您仍然必须小心:如果time1和中的字符串time2包含字符^*+.?\[|{$,则字符串将被解释为正则表达式。对于问题中显示的字符串来说这不是问题(它们不包含正则表达式活动字符),但是,如果其他字符串给您带来令人惊讶的结果,则这可能是原因。

相关内容