awk 想要按小时和变量总计

awk 想要按小时和变量总计

我能够运行它并且工作正常 - 注意:字段 $1 是一个带有时间/日期标记的字段..

gawk -F ":" "{ print $1 }" /cygdrive/c/counting/ourlog | sort | uniq -c | sort -r
  57339 2014-03-21 09
  54290 2014-03-21 08
  54036 2014-03-21 10
  53254 2014-03-21 11
  52777 2014-03-21 12
  50785 2014-03-21 07
  49729 2014-03-21 16
  44459 2014-03-21 15
  43932 2014-03-21 13
  43335 2014-03-21 06
  40952 2014-03-21 14
  40864 2014-03-21 17

现在,我想要做的是隐藏前 10 行(它们是前面带有 # 的注释)——这可能会有所不同。因此,我们想要查找以 # 开头的前 xx 行。

我们将脚本更改为:

gawk -F ":" "{ print $1 }" /cygdrive/c/counting/ourlog | sort | uniq -c | sort -r | gawk -v MyID="$id" '/#/{n++}; END {print n+0}' | gawk "NR> MyID "

但这不起作用。如果我们再做一些更改 - 我们会看到期望的结果:

gawk -F ":" "{ print $1 }" /cygdrive/c/counting/ourlog | gawk "NR>10" | sort | uniq -c | sort -r

我知道我可以实际输入 10 来跳过前 10 或 20 行。但是,我希望这是一个计算值。

答案1

以下awk代码仅跳过最初的注释,然后print $1跳过其余行:

gawk -F: -v c=1 '/^[^#]/ {c=0} c==0 { print $1 }' ourlog

在程序启动之前,该变量c被设置为 1。一旦发现非注释行,该变量c就会被设置为零,并且在其余的执行过程中保持这种状态。当 时c==0,打印语句被执行。

如果你只是想消除所有注释,那么代码就简单得多:

gawk -F: '/^[^#]/ { print $1 }' ourlog

上面的代码根据正则表达式检查每一行^[^#],仅当第一个字符不是 时才匹配#。如果匹配(行而不是注释),则执行打印语句。

答案2

由于我原来的帖子因语法问题而被编辑..我必须将其作为新的“答案”...

这是解决这个问题的另一种方法,直到今天早上我才想到。

sed "/#/d" "/cygdrive/c/!chkout/ourlog" | gawk -F ":" "{print $1}"  | sort | uniq -c | sort -r

答案3

我不太确定你想要做什么,因为你没有显示实际的输入,只是显示你想要的输出以及在各个阶段使用的各种代码。但是,我认为以下内容将满足您的要求(确保您-F:在命令行上设置。如果没有,我会尝试描述每个部分,以便您了解如何修改它。

!/^#/ {                                      # do the following on all rows that don't begin 
                                             # with `#`

    a[$1]++                                  # store column 1 as the key in an array and
                                             # increment the value for each occurrence
}

END {                                        # do the following after reading the entire file

    PROCINFO["sorted_in"] = "@ind_num_desc"; # set array traversal as numeric index descending
                                             # (requires gawk >= 4.0, otherwise, additional code
                                             # will be needed)

    for (i in a) {                           # loop through the array setting i as the index of
                                             # the current entry

        print a[i], i;                       # print the value (row count) and the index (the
                                             # row)
    }
}    

我认为你不再需要传递一个变量,因为它似乎只是用来确定要跳过多少个初始注释行,但如果你想这样做,你几乎在你的例子中就有了它,但每次你invoke gawk,这是一个新实例。您将该变量传递给了使用它的实例之前的实例。因此,在上面的示例中,您需要将其更改为:

gawk -F ":" "{ print $1 }" /cygdrive/c/counting/ourlog \
    | sort | uniq -c | sort -r                         \
    | gawk '/#/{n++}; END {print n+0}'                 \
    | gawk -v MyID="$id" "NR> MyID "

但所有这些都可以结合起来。最后两行只是计算行数#,我猜想,尝试将该值传递给另一个实例,但您只是将其打印到 STDOUT,所以我不确定它是如何工作的。因此,只需修改第一行即可让 awk 跳过这些行:

gawk -F: '!/^#/ { print $1 }' /cygdrive/c/counting/ourlog \
    | sort | uniq -c | sort -r

如果这就是您想要的,并且您想避免所有管道,那么上面的代码就可以工作。

相关内容