更新文件中多个日期的日期格式

时间:2015-10-01 20:11:23

标签: bash date unix awk

我尝试更新包含多个日期的文件。这是一个示例文件:

firstname   lastname    startdate   enddate
bob smith   6/1/2014    6/30/2014
sue jones   5/31/2014   6/15/2014

我想要得到的是:

firstname   lastname    startdate   enddate
bob smith   20140601 0000   20140630 0000
sue jones   20140531 0000   20140615 0000

我可以使用awk获得第一个日期,但是第二个日期会在第二行结束。

$ awk -F '\t' 'NR <=1 {print;next} {printf("%s\t%s\t",$1,$2);system("date -j -f '%m/%d/%Y' "$3" +%Y%m%d\\ 0000");system("date -j -f '%m/%d/%Y' "$4" +%Y%m%d\\ 0000");}' dates.txt 

firstname   lastname    startdate   enddate
bob smith   20140601 0000
20140630 0000
sue jones   20140531 0000
20140615 0000

我无法找到有人试图更改文件中两个日期的示例。有人可以帮我弄清楚如何在一行上获得每行的输出吗?

3 个答案:

答案 0 :(得分:2)

试试这个:

$ awk -F'[ \t/]+' 'NR==1{print;next;} {printf "%s %s  %04i%02i%02i 0000  %04i%02i%02i 0000\n",$1,$2,$5,$3,$4,$8,$6,$7;}' dates.txt
firstname   lastname    startdate   enddate
bob smith  20140601 0000  20140630 0000
sue jones  20140531 0000  20140615 0000

这是在GNU awk下测试的,但我希望它可以移植到其他awks。

如何运作

  • -F'[ \t/]+'

    这会将字段分隔符设置为空白,制表符或斜杠的任意组合。这样,我们可以将年,月和日作为单独的字段进行访问。如果它没有准确地表示实际输入文件中的字段分隔符,则可能需要更改它。

  • NR==1{print;next;}

    标题行按原样打印。

  • printf "%s %s %04i%02i%02i 0000 %04i%02i%02i 0000\n",$1,$2,$5,$3,$4,$8,$6,$7;

    第一个之后的所有行都重新格式化为printf语句。您可以调整格式字符串以生成您喜欢的任何内容。特别是,如果您的字段以制表符分隔,则需要添加标签。

制表符分隔版

如果输入和输出是以制表符分隔的:

$ awk -F'[\t/]+' 'NR==1{print;next;} {printf "%s\t%s\t%04i%02i%02i 0000\t%04i%02i%02i 0000\n",$1,$2,$5,$3,$4,$8,$6,$7;}' dates.txt
firstname       lastname        startdate       enddate
bob     smith   20140601 0000   20140630 0000
sue     jones   20140531 0000   20140615 0000

在上文中,我假设将20140601 0000视为一个字段。如果没有,那么带有0000的格式字符串部分将需要替换为\t0000

答案 1 :(得分:1)

$ cat tst.awk
BEGIN { FS=OFS="\t" }
{
    for (i=3; i<=4; i++) {
        $i = (split($i,a,"/")>2 ? sprintf("%04d%02d%02d 000",a[3],a[1],a[2]) : $i)
    }
    print
}

$ awk -f tst.awk file
firstname       lastname        startdate       enddate
bob     smith   20140601 000    20140630 000
sue     jones   20140531 000    20140615 000

答案 2 :(得分:0)

您不需要系统调用来重新排列日期字段。但是对于其他用途,还有另一种gawk解决方案。

如果你需要调用另一个进程并在脚本中捕获输出,你可以使用这个习语

"subprogram" |& getline results

适合您的情况

awk -F'\t' -vOFS='\t' '
       NR==1{print;next} 
            {"date -j -f '%m/%d/%Y' "$3" +%Y%m%d\\ 0000" |& getline d1;
             "date -j -f '%m/%d/%Y' "$4" +%Y%m%d\\ 0000" |& getline d2;
             print $1,$2,d1,d2}' file