【问题标题】:awk unable to compare time with defined valueawk 无法将时间与定义的值进行比较
【发布时间】:2014-09-24 04:21:40
【问题描述】:

如何使用 awk 比较时间。我一直在尝试使用以下方法,但失败了。

只要“滞​​后”超过值“24:00:00”,就应打印以下文件中的第 4 列。但就我而言,只有 2717:33:54 被打印出来。应该在哪里打印所有行。

bash-4.2$ cat test
Source  Destination     State           Lag             Status
Data1   Test:/data1     Complted        1239:30:37      Quiescing
Data2   Test:/data2     Complted        1239:30:13      Idle
Data3   Test:/data3     Complted        1208:37:21      Idle
Data4   Test:/data4     Complted        1208:36:46      Idle
Data5   Test:/data5     Complted        1239:29:41      Idle
Data6   Test:/data6     Complted        1239:29:26      Idle
Data7   Test:/data7     Complted        1239:28:52      Idle
Data8   Test:/data8     Complted        2717:33:54      Quiescing

threhold=24:00:00

cat test | awk -v threshold=$threshold '$4 > threshold'
Source  Destination     State           Lag             Status
Data8   Test:/data8     Complted        2717:33:54      Quiescing

【问题讨论】:

  • @jaypal sn-p 中的变量名有错字。 threhold 在分配线上。这会将我的输出更改为我更正时得到的输出。话虽如此,我不知道 awk 将如何比较这些字段。糟糕,我会猜。大概是字符串长度,然后是位置字符值。它绝对不会做的是将它们计算为时间。
  • @EtanReisner 啊,我只是复制粘贴。
  • awk 不是特别适合使用日期/时间结构 - 它会将您的字段视为字符串,而不是您理解的间隔;因此,它正在进行字典(即字典顺序)比较。您可能想尝试pythonperl 以获得更好的日期/时间处理功能。
  • 或使用具有内置日期/时间函数的 GNU awk,但对于这种琐碎的情况,这不是必需的。

标签: bash awk


【解决方案1】:

字符串 2712:22:54 大于字符串 24:00:00 因为每个 (2) 的第一个字符是相同的,但是当您到达第二个字符时 7 大于 4 并且所有其他字符串小于字符串24:00:00,因为它们都以1 开头。也许您想使用0024:00:00 作为阈值?或者将所有字符串转换为整数(例如 secs = hours * 60 * 60 + mins * 60)以进行数字比较。

【讨论】:

    【解决方案2】:

    正如其他人所建议的那样,将 24:00:00 与 1239:30:37 进行比较不会达到您想要的效果,因为比较是按字典顺序进行的(即按字母顺序逐一比较字符)。一种选择是在几秒钟内完全工作,而是进行数值比较。以下是使用 Perl 单行代码的方法:

    perl -slane 'sub tt{($h,$m,$s)=split /:/,shift; return $h*3600+$m*60+$s}
                 print if tt($F[3])>tt($t)' -- -t="$threshold" file
    

    子例程tt 拆分它在“:”上传递的字符串。给定格式为“小时:分钟:秒”的输入,它返回总秒数。 -a 启用自动拆分模式,这意味着每行输入的第 4 列存储在 $F[3] 中。以秒为单位的列值与在行尾传递的参数值进行比较。打印滞后大于$t 的行。

    测试一下:

    $ perl -slane 'sub tt{($h,$m,$s)=split /:/,shift; return $h*3600+$m*60+$s} print if tt($F[3])>tt($t)' -- -t=24:00:00 file
    Data1   Test:/data1     Complted        1239:30:37      Quiescing
    Data2   Test:/data2     Complted        1239:30:13      Idle
    Data3   Test:/data3     Complted        1208:37:21      Idle
    Data4   Test:/data4     Complted        1208:36:46      Idle
    Data5   Test:/data5     Complted        1239:29:41      Idle
    Data6   Test:/data6     Complted        1239:29:26      Idle
    Data7   Test:/data7     Complted        1239:28:52      Idle
    Data8   Test:/data8     Complted        2717:33:54      Quiescing
    

    当您使用 awk 标记问题时,以下是您如何使用 awk 来做同样的事情:

    awk 'function tt(t){split(t,a,/:/); return a[1]*3600+a[2]*60+a[3]}
         tt($4)>tt(t)' t="$threshold" file
    

    逻辑与上面的 Perl 示例相同。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多