使用awk处理多行变量,打印满足条件的未修改行

时间:2019-03-11 17:13:44

标签: shell unix awk sed posix

我有一个变量,包含多行文件的内容。变量由众多命令(awksed,...)解析,这些命令充当变量的过滤器和后处理器。

echo "$variable" | awk1 | sed1 | awk2

问题不是自己处理,而是我在处理过程中修改了这一行,从而失去了对变量原始值的跟踪。问题是最后一个awk会执行条件检查,该检查是否根据结果返回原始变量。这就是我的问题所在。

我认为在回显后用原始行创建此变量是一个好主意,但是我在以下子shell中继承它的任何尝试都使我失败了。 该解决方案必须是便携式的(符合POSIX标准)

变量格式:

John Smith - - [21/Mar/2017:09:24:33 +0100] Physics 
Adam Miller - - [22/Feb/2019:09:24:33 +0100] Chemistry 

我想将此文件中的日期与YYYYMMDDHHMMSS格式的给定日期(例如20180101151515)进行比较,如果一行中包含日期,则要打印整行。

到目前为止,我的代码:

date_after="19960101151515"
process=$(echo "$variable" |awk -F' - - ' '{print $2}' | sed "s/Jan/01/; s/Feb/02/;
    s/Mar/03/; s/Apr/04/; s/May/05/; s/Jun/06/; s/Jul/07/;
    s/Aug/08/; s/Sep/09/; s/Oct/10/; s/Nov/11/; s/Dec/12/" | awk -F'[/:\\[ ]' -v date="$date_after" '{b=$4$3$2$5$6$7; if (b > date) {print $0}}')

1 个答案:

答案 0 :(得分:0)

sedawkgrepcut,...的任何组合通常都可以用单个awk代替。这也使您可以存储原始数据并根据条件将其返回。 您可以轻松地看到以下awk完成了您感兴趣的转换(第一次awk和sed)

awk '{ t=$0
       match(t,"\\["); t=substr(t,RSTART+1)
       match(t," ")  ; t=substr(t,1,RSTART-1); split(t,a,"[/:]")
       day=a[1]; year=a[3]; hhmmss=a[4]a[5]a[6]; 
       month=sprintf("%02d",(match("JanFebMarAprMayJunJulAugSepOctNovDec",a[2])+2)/3)
       print year month day hhmmss, t}'

因此,现在您可以在t上插入条件,并在需要时返回原始$0

awk -v d="$date_after" '
     { t=$0
       match(t,"\\["); t=substr(t,RSTART+1)
       match(t," ")  ; t=substr(t,1,RSTART-1); split(t,a,"[/:]")
       day=a[1]; year=a[3]; hhmmss=a[4]a[5]a[6]; 
       month=sprintf("%02d",(match("JanFebMarAprMayJunJulAugSepOctNovDec",a[2])+2)/3)
     }
     (t > d) { print $0 }'

基于:convert month from Aaa to xx in little script with awk