【问题标题】:Delete a line with a pattern删除带有图案的线条
【发布时间】:2010-11-28 08:29:18
【问题描述】:
您好,我想从文件中删除与特定模式匹配的行
我使用的代码是
BEGIN {
FS = "!";
stopDate = "date +%Y%m%d%H%M%S";
deletedLineCtr = 0; #diagnostics counter, unused at this time
}
{
if( $7 < stopDate )
{
deletedLineCtr++;
}
else
print $0
}
代码说文件有行“!”分隔的第 7 个字段是日期 yyyymmddhhmmss 格式。该脚本删除日期小于系统日期的行。但这不起作用。谁能告诉我原因?
【问题讨论】:
标签:
unix
shell
scripting
sed
awk
【解决方案1】:
awk(1) 作业是星期二到期吗?真的吗?? :-)
好吧,我不确定你到底想要什么,所以我做了一些猜测。此 awk 程序获取当前时间,然后删除文件中少于该时间的每一行。我留下了一个调试打印。
BEGIN {
FS = "!"
stopDate = strftime("%Y%m%d%H%M%S")
print "now: ", stopDate
}
{ if ($7 >= stopDate) print $0 }
$ cat t2.data
!!!!!!20080914233848
!!!!!!20090914233848
!!!!!!20100914233848
$ awk -f t2.awk < t2.data
now: 20090914234342
!!!!!!20100914233848
$
【解决方案2】:
首先调用date,将格式化的日期作为参数传递:
awk -F'!' -v stopdate=$( date +%Y%m%d%H%M%S ) '
$7 < stopdate { deletedLineCtr++; next }
{print}
END {do something with deletedLineCrt...}
'
【解决方案3】:
您可能需要运行 date 命令(可能带有反引号)才能将日期输入到 stopDate。如果您使用编写的代码打印 stopDate,它将包含“date + ...”,而不是一串数字。这是你问题的根本原因。
很遗憾……
我找不到任何证据表明反引号适用于任何版本的 awk(旧 awk、新 awk、GNU awk)。因此,您要么需要将代码迁移到 Perl(Perl 最初被设计为“awk-killer” - 并且仍然包含 a2p 以将 awk 脚本转换为 Perl),或者您需要重新考虑如何设置日期。
看到@DigitalRoss 的回答,gawk 中的strftime() 函数为您提供了您想要的格式(像我一样检查'info gawk')。
修复后,您应该会删除正确的行。