在bash中使用awk比较日期

时间:2016-10-09 19:48:15

标签: bash shell date awk

所以我有一个文件,每行都有一些信息和日期(生日)。我想在给定日期之后打印带日期的行。我用这个awk命令

awk -F '|' 'FNR>1 $dateA<=$5 {print $1" "$2" "$3" "$4" "$5" "$6" "$7" "$8}' $FILE

但它无法正常工作(所有文件行都打印出来)。日期为YYYY-MM-DD格式,因此字母顺序也是按时间顺序排列的。

编辑:输入文件中的某些行

1099511628908|Chen|Wei|female|1985-08-02|2010-05-24T20:52:26.582+0000|27.98.244.108|Firefox
1099511633435|Smith|Jack|male|1981-04-19|2010-05-26T03:45:11.772+0000|50.72.193.218|Internet Explorer
1099511635042|Kiss|Gyorgy|male|1984-09-14|2010-05-16T22:57:41.808+0000|91.137.244.86|Chrome
1099511635218|Law-Yone|Eric|male|1987-01-20|2010-05-26T20:10:22.515+0000|203.81.95.235|Chrome
1099511638444|Jasani|Chris|female|1981-05-22|2010-04-29T20:50:40.375+0000|196.223.11.62|Firefox
2199023256615|Arbelaez|Gustavo|male|1986-11-02|2010-07-17T18:53:47.633+0000|190.96.218.101|Chrome

3 个答案:

答案 0 :(得分:2)

正如其他人所说,shell中不会扩展单引号中的变量。 Awk会看到变量的名称,而不是它的值。

一种可能的解决方案是这样做(假设比较字符串是正确的):

dateA='1985-01-01'
infile='file to read values from'
awk -F '|' -v dateA="$dateA" '{if (FNR>1 && dateA<=$5) {print}}' "$infile"

更惯用的解决方案(不太清楚):

awk 'FNR>1 && dateA<=$5' FS='|' dateA="$dateA" "$infile"

或(是的,需要所有引用):

awk 'FNR>1 && "'"$dateA"'"<=$5' FS='|' "$infile"

但在考虑使用此选项之前read this about code injection

答案 1 :(得分:0)

为此起作用:

awk -vdateA=1985-01-01 -F '|' 'FNR>1 dateA<=$5' $FILE
    ~~~~~~~~~~~~~~~~~~

答案 2 :(得分:0)

您的变量$dateA是一个shell变量。如果你将它嵌入单引号之间,它将不会被shell解释(它不会被它的值替换)并且将“按原样”转发给awk。

Awk收到字符串$dateA。它认为它是一个awk变量,但它没有任何值,所以它使用空字符串代替。

表示所有日期都被视为“更大”到空字符串,因此所有行都匹配并打印出来。

有几个解决方案。除了Gilles Quenot的那个,你手动指示awk dateA是一个shell变量,你也可以把它“带引号”,如下所示:

awk -F '|' 'FNR>1 '$dateA'<=$5 {print $1" "$2" "$3" "$4" "$5" "$6" "$7" "$8}' $FILE
                  ^      ^

当日期是整数值时,它会起作用,但当它是YYYY-MM-DD格式时,则不起作用。在后一种情况下,我们需要...用引号转义变量来告诉awk这是一个字符串。

我们希望做一些看起来像"$dateA"的事情。由于我们已添加单引号而不是将$dateA传递给awk,因此我们必须在其周围添加双引号:"'$dateA'"。这样,shell首先用其值替换dateA,然后删除单引号,并将"1985-08-23"赋予awk。

所以这一行是:

awk -F '|' 'FNR>1 && "'$dateA'"<=$5 {print $1" "$2" "$3" "$4" "$5" "$6" "$7" "$8}' $FILE

编辑:不确定这是否取决于awk版本,但我在此示例中遇到语法错误,并且还必须将FNR>1 '$date'<$5替换为FNR>1 && '$date'<$5(附加&&)。 GNU awk在这里。