3

我有一个记录文件,按日期存储我们系统的状态。生成它的脚本通过 cron 运行,因此文件不断变长。我编写了一个脚本,它遍历每一行来处理它,这需要很长时间才能完成。我听说 awk 在处理大型文本文件时要快得多。我的问题是我从来没有使用过它。是否可以使用 awk 获取日期范围内的所有条目?日期都以秒为单位,因为它们是用 生成的date +%s。这是一个输出示例,我希望能够快速找到某个范围内的数据。例如,我怎样才能得到第一列在 1344279903 和 1344280204 之间的所有行?

1344279903 |  0  | 0 | node  |  1
1344279904 |  0  | 0 | node  |  2
1344279905 |  0  | 0 | node  |  3
1344280202 |  0  | 0 | node  |  1
1344280203 |  0  | 0 | node  |  2
1344280204 |  99  | 0 | node  |  3
4

3 回答 3

4

您可以像这样使用条件表达式:

awk '$1 >= 1344279903 && $1 <= 1344280204 { print $0 }' data.txt
于 2012-08-06T19:18:00.040 回答
3

用awk?

awk -F'|' '1344279903 <= $1 && $1 <= 1344280204' file

用sed?

sed -n '/1344279903/,/1344280204/p' file

您可以通过在最后一个 print 语句之后显式退出来使 awk 表达式更加高效:

awk -F'|' '1344279903 <= $1 && $1 <= 1344280204{ print $0; } $1 == 1344280204{ exit; }' file
于 2012-08-06T19:20:11.303 回答
2

这是我对此的看法:

#!/usr/bin/awk -f

BEGIN {
  start=ARGV[1]; ARGV[1]="";
  end=ARGV[2]; ARGV[2]="";
}

$1 < start { next }

$1 > end { exit }

1

这是如何运作的?

awk 使用一系列“条件{命令}”块应用于每一行输入。BEGIN 块是在输入开始之前运行的“魔术”块。(输入结束有一个类似的 END 块,但我们在这里没有使用它。)

  • 在此脚本中,我们的 BEGIN 块根据您的命令行设置“开始”和“结束”变量,然后清空这些变量,以便 awk 不会尝试将它们解释为输入文件。
  • 下一个条件导致 awk 跳过在您的开始日期之前出现的任何行。当我们运行时next,我们告诉 awk 读取新的输入行并重新开始处理它的条件。
  • 下一个条件会导致 awk 在到达您要打印的日期范围的末尾时退出。(当然,这假设您的输入数据是按时间顺序排列的。)
  • 最后一个条件本身就是一个“1”。这是“打印当前行”的 Awk 简写,如果前面的条件都不满足,它将执行此操作(因为前面的两个条件都会阻止我们到达脚本中的这一点)。

它在您的示例数据上起作用:

ghoti@pc$ ./awkdate 1344279905 1344280203 data.txt
1344279905 |  0  | 0 | node  |  3
1344280202 |  0  | 0 | node  |  1
1344280203 |  0  | 0 | node  |  2
ghoti@pc$ 
于 2012-08-06T19:33:05.883 回答