【问题标题】:Linux shell scripting - Simple awk script issueLinux shell 脚本 - 简单的 awk 脚本问题
【发布时间】:2014-10-28 02:55:49
【问题描述】:

我正在尝试做一个非常简单的 awk 脚本练习,但不知道为什么它不起作用。

应使用 awk 脚本仅显示以 2012 开头的条目,因此给出以下输入文件:

  2009 Dec X 29.44
  2009 Dec Y 32.32
  2012 Jan X 321.11
  2012 Feb Y 1.99
  2012 Feb X 32.99
  2012 Mar X 11.45
  2010 Jan X 14.75
  2011 Feb Y 21.00
  2011 Mar X 7.77

输出应该如下:

 % awk -f awkscriptfile inputfile
  Data for year 2012
  ==================
  Jan : 321.11
  Feb : 1.99
  Feb : 32.99
  Mar : 11.45
  ===================
  volume for 2012 is: 367.54
  4 records processed
  %

但是,我得到的是:

% awk -f awkscriptfile inputfile
    Data for year 2012
    ==================================
     2009 Dec X 29.44
     2009 Dec Y 32.32
     2012 Jan X 321.11
    Jan  :  321.11
     2012 Feb Y 1.99
    Feb  :  1.99
     2012 Feb X 32.99
    Feb  :  32.99
     2012 Mar X 11.45
    Mar  :  11.45
     2010 Jan X 14.75
     2011 Feb Y 21.00
     2011 Mar X 7.77
    ==================================
    volume for 2012 is: $sum
    $count records processed
%

所以 awk 脚本显然比它应该打印的要多得多,并且由于某种原因 sum 和 count 变量没有被打印出来。

这是我的 awk 脚本代码:

BEGIN {
 print "Data for year 2012"
 print "=================================="
 count = 0
 sum = 0
}
$1 ~ /2012/ {
 print $2, " : ", $4
 count++
 sum += $4
}
END {
 print "=================================="
 print "volume for 2012 is: $sum"
 print "$count records processed"
}

从我正在查看的所有参考资料来看,我认为这段代码没有理由不工作。希望其他人能告诉我我做错了什么。

【问题讨论】:

  • 那个确切的输入和那个确切的脚本在这里没有这样做。您确定这就是您完全使用的脚本吗?因为这看起来很像您使用杂散的真值模式或调试{print} 操作获得的输出。
  • 另外,您不要在变量上使用$,并且它们不会插入到字符串中。所以最后两行希望成为print "volume for 2012 is : "sumprint count " records processed"
  • 我实际上在脚本顶部有一个以“//”而不是“#”开头的注释,并且更改它似乎已经修复了它。我认为两者都可以使用 shell 脚本,但我想不是。您提供的可变修复当然也有效。非常感谢!
  • Awk 不是外壳;他们是两个不同的东西。但是,它们确实彼此共享注释语法以及许多其他 UNIX 实用程序。我正在尝试将 shell 风格的 # cmets 与 C++ 风格的 // cmets 混合在一起的任何编程语言,但没有想到..
  • 而且// 在 bash 中也不起作用......虽然我想可能是 csh。是的,// 是一个匹配任何内容的正则表达式,因此将运行默认操作来打印该行(虽然我很惊讶你的其余评论没有引起问题,但我想 awk 只是看到这些词是空白的变量什么的。

标签: linux shell awk


【解决方案1】:
awk -v y="2012" '$1==y{a[NR]=$2":"$4;s+=$4;c++}
    END{line="===================";
    printf "Data for year %s\n%s\n",y,line;
    for(i=1;i<=NR;i++)if(a[i])print a[i]
    printf "%s\nvolume for %s is: %.2f\n%d records processed\n", line, y, s, c}' file

使用您的数据,它会输出:

Data for year 2012
===================
Jan:321.11
Feb:1.99
Feb:32.99
Mar:11.45
===================
volume for 2012 is: 367.54
4 records processed

【讨论】:

    【解决方案2】:

    这是您的脚本的修改版本

    输入

    akshay@Aix:/tmp$ cat infile
      2009 Dec X 29.44
      2009 Dec Y 32.32
      2012 Jan X 321.11
      2012 Feb Y 1.99
      2012 Feb X 32.99
      2012 Mar X 11.45
      2010 Jan X 14.75
      2011 Feb Y 21.00
      2011 Mar X 7.77
    

    脚本

    akshay@Aix:/tmp$ cat stat_data.awk
    BEGIN{
    
        if( ARGC < 2 || year=="")
        {
            error=1
            print "\n\t\tUsage   : awk -vyear=<year> -f script.awk <input file>"
            print "\t\tExample : awk -vyear=2012 -f script.awk test.txt\n"
            exit
        }
    
            print "Data for year "year
            print "=================================="
    
    }
    $1==year{
            print $2":"$4
            sum+=$4
            count++
    }
    END{
         if(!error)
         {
            print "=================================="
            print "volume for "year" is: "sum
            print count" records processed"
         }
    }
    

    如何执行?

    akshay@Aix:/tmp$ awk -vyear=2012 -f stat_data.awk  infile
    

    输出

    Data for year 2012
    ==================================
    Jan:321.11
    Feb:1.99
    Feb:32.99
    Mar:11.45
    ==================================
    volume for 2012 is: 367.54
    4 records processed
    

    【讨论】:

      猜你喜欢
      • 2011-05-07
      • 2016-06-10
      • 1970-01-01
      • 1970-01-01
      • 2015-04-08
      • 1970-01-01
      • 2021-11-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多