【问题标题】:Using awk to find missing field in line使用 awk 查找行中缺失的字段
【发布时间】:2014-04-01 08:08:16
【问题描述】:

我有几千行文件,其中列出了每十五分钟存储一次数据的目录。每个目录的名称都是一个以 00、15、30 或 45 结尾的时间戳。

此文件包含每个时间戳以及存在的十五分钟间隔。例如,

io_credit 2014030100 00 15 30 45
io_credit 2014030101 15 30
io_credit 2014030102 45
io_credit 2014030103 00 15 30 45

如您所见,某些时间戳缺少特定的 15 分钟间隔。另请注意,写入时间戳的顺序始终相同,即使缺少时间戳也是如此。因此,如果 15 是唯一缺少的时间戳,那么 00、30 和 45 将按顺序排列。同样适用于所有其他时间戳。所以换句话说,你永远不会看到类似的东西

45 15 30

我一直在努力使用 awk 找出打印出每个时间戳的方法以及该时间戳的缺失间隔。

以下是我为仅包含五个字段的行编写的内容:

cat file | awk '{if (NF == 5) for (i = 3; i <= 5; i++) { if (i == 3 && $i == "00") continue; else if (i == 3 && $i == "15") missing="00"; continue; if (i == 4 && $i == "15") continue; else if (i == 4 && $i == "30") missing=missing " 15"; if (i == 5 && $i == "30") missing=missing "45"; else missing=missing "30"; } {print $1,$2, missing }}'

但是,对于与 (NF == 5) 限定符匹配的每一行,这只会打印“00”而不是其他任何内容。

我在这里做错了什么?

【问题讨论】:

  • 如果你想让所有数据看起来都一样,逻辑有什么好处?只需 awk '{print $1 " " $2 "00 15 30 45"}' file 祝你好运。
  • 不,我需要从另一个位置复制数据,但仅限于那些丢失的间隔。这就是为什么我需要每个时间戳的缺失间隔列表。如果 00、15 和 45 在那个时间戳中,我只想复制 30,而不是全部四个。
  • 从您的描述和代码中我(至少)不清楚。您可以使用示例输入的预期输出更新问题吗?祝你好运。
  • 请注意,您不需要cat file | awk ...。可以直接使用awk ... file

标签: awk


【解决方案1】:

下面查看文件中的每一行。如果该行具有所有时间戳,则将其忽略。如果没有,则打印缺少的时间戳:

$ awk 'NF==6 {next} {c="00 15 30 45"; for(i=3;i<=NF;i++){sub($i,"  ",c)}; print $2" " c} ' file
2014030101 00       45
2014030102 00 15 30  

它是如何工作的: 如果所有时间戳都出现在一行上,那么该行有 6 个字段。所有带有六个字段 (NF==6) 的点赞都会被忽略。否则,变量c 设置为"00 15 30 45"。然后,代码循环遍历每个时间戳,如果存在,则将其从c 中删除。将打印时间戳和 c 中剩余的任何内容(这将是缺少的字段)。

【讨论】:

  • 谢谢,我知道这样的做法是正确的,但我的大脑一直走入死胡同。
猜你喜欢
  • 1970-01-01
  • 2021-11-25
  • 2014-09-08
  • 1970-01-01
  • 1970-01-01
  • 2012-07-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多