【问题标题】:How can I pass shell variables to awk? [duplicate]如何将 shell 变量传递给 awk? [复制]
【发布时间】:2012-04-01 10:44:35
【问题描述】:

我有以下简单的脚本。但是,它错误地将计数器结果设为 0。

#!/usr/local/bin/bash
f_name="test.stat"
S_Date="2012-02-10"
E_Date="2012-02-13"

awk 'BEGIN {FS="\t";s_time = mktime($S_Date);e_time = mktime($E_Date);counter=0}
     {if ($1 >= s_time && $1 <= e_time) counter++}
     END{print counter}' $f_name

数据文件格式为:$Date $val

【问题讨论】:

  • 你最好在 unix.stackexchange.com 上问这个
  • 这是一个awk 程序,主题为 SO。
  • 说真的:这个问题怎么会有近 14,000 次浏览,却只有两票? (我很好奇为什么有人只有不到 100 个声望和 2 个金徽章。就是这样。)
  • 我怀疑这是因为人们来到这里希望找到有关多个条件的一些见解,结果发现问题实际上与变量引用有关。

标签: awk


【解决方案1】:

awk 命令用单引号括起来,所以$S_DATE$E_DATE 是按字面意思理解的。您有几个选择:

#!/usr/local/bin/bash
f_name="test.stat" S_Date="2012-02-10" E_Date="2012-02-13"

awk 'BEGIN {FS="\t";s_time = mktime('"$S_Date"');e_time = mktime('"$E_Date"');counter=0} {if($1 >= s_time && $1 <= e_time) counter++} END{print counter}' "$f_name"
#!/usr/local/bin/bash
f_name="test.stat" S_Date="2012-02-10" E_Date="2012-02-13"

awk "BEGIN {FS=\"\\t\";s_time = mktime($S_Date);e_time = mktime($E_Date);counter=0} {if(\$1 >= s_time && \$1 <= e_time) counter++} END{print counter}" "$f_name"

或者,我最喜欢的:

#!/usr/local/bin/bash
f_name="test.stat" S_Date="2012-02-10" E_Date="2012-02-13"

awk "$f_name" <<EOF
BEGIN {
    FS="\t"
    s_time = mktime($S_Date)
    e_time = mktime($E_Date)
    counter=0
} 
{ if(\$1 >= s_time && \$1 <= e_time) counter++ } 
END{print counter}
EOF

【讨论】:

  • 您也可以将 shell 变量作为 awk 变量传递:awk -F '\t' -v s_date="$S_Date" -v e_date="$E_Date" 'BEGIN {s_time = mktime(s_date); e_time = mktime(e_date); ...(这是我的最喜欢的;)
  • @Kevin,尽管数据文件的日期在该范围内,但您的前两个选项都返回 0
  • @glenn jackman,收到您的建议的语法错误消息,它应该在引号内还是在 bash 脚本中调用后的其他内容?