在awk参数中使用日期命令

时间:2018-10-03 15:45:35

标签: shell date awk

我有一个看起来像这样的文件

server1-adm.test.com,/var,dir,29987,2007-12-03 15:52:43,root,root
server2.fs.com,/DATA_File.out,file,299076487,2008-10-15 05:12:23,user1,group1
server3-prd.mod.com,/opt,dir,29987,2009-05-03 00:13:23,user1,group1
server4,/var/tmp/xxz.zip,file,400,2007-12-03 15:52:43,root,root
server1-adm.test.com,/usr,dir,34299876,2006-12-03 16:52:43,root,root
server3-prd.mod.com,/local/home,dir,400,2009-05-03 12:13:23,user2,group1

第五列是我要修改的date + time值。我尝试一起使用多个awk语句,但是它看起来太混乱了,容易出错。 我不使用多个语句进行日期格式转换,而是如何在awk中使用date系统命令转换为以下结果。

server1-adm.test.com,/var,dir,29987,2007-12-03 03:52:43 PM,root,root
server2.fs.com,/DATA_File.out,file,299076487,2008-10-15 05:12:23 AM,user1,group1
server3-prd.mod.com,/opt,dir,29987,2009-05-03 00:13:23 AM,user1,group1
server4,/var/tmp/xxz.zip,file,400,2007-12-03 03:52:43 PM,root,root
server1-adm.test.com,/usr,dir,34299876,2006-12-03 04:52:43 PM,root,root
server3-prd.mod.com,/local/home,dir,400,2009-05-03 12:13:23 PM,user2,group1

date -d "2007-12-03 15:52:43" +%Y/%m/%d:%H%M%S行中的内容。我不知道如何在date命令中获得AM / PM。

我已经有多个awk语句作为脚本的一部分一起运行,以对同一传入文件执行其他文本修改,因此我想使用awk + ​​date语句来执行此操作。

4 个答案:

答案 0 :(得分:3)

如果您可以使用GNU awk,则它提供了一些时间函数,这些函数使您的程序运行速度比对CSV文件的每一行调用shell + date都要快:

awk 'BEGIN { FS = OFS = "," } { gsub("[-:]", " ", $5); $5 = strftime("%F %r", mktime($5)) } 1'

展开形式:

awk '
    BEGIN { FS = OFS = "," }

    {
        gsub("[-:]", " ", $5)
        $5 = strftime("%F %r", mktime($5))
    }

    1
'

如果您确实要使用外部date命令(如您在问题中所述),请使用GNU awk协同处理,以便仅启动一个date命令并重新使用在每一行:

awk 'BEGIN { FS = OFS = ","; cmd = "stdbuf -oL date -f - +%F\" \"%r" } { print $5 |& cmd; cmd |& getline $5 } 1'

展开形式:

awk '
    BEGIN {
        FS = OFS = ","
        cmd = "stdbuf -oL date -f - +%F\" \"%r"
    }

    {
        print $5 |& cmd
        cmd |& getline $5
    }

    1
'

但是您确实应该采用第一个解决方案。

答案 1 :(得分:1)

请您尝试以下。

awk -F'[ ,]' '{split($6,array,":");$6=array[1]>12?sprintf("%02d",array[1]-12)":"array[2]":"array[3]" PM":(array[1]==12?$6 " PM":$6 " AM")} 1'  Input_file

说明: 在此处也为上述代码添加了说明。

awk -F'[ ,]' '                                                         ##Making field separator as space and comma for all the lines of Input_file.
{
  split($6,array,":")                                                  ##using split function to split 6th field of current line by making : as field sep for it.
  $6=array[1]>12?sprintf("%02d",array[1]-12)":"array[2]":"array[3]" PM" :$6 " AM" ##re-creating $6 value by checking condition if its 1st value array value which is time is greater than 12 than subtracting its value with 12 here and adding PM and AM according to it too.
}
1                                                                      ##Mentioning 1 will print the edited/non-edited value of line.
' Input_file                                                       ##Mentioning Input_file name here.

答案 2 :(得分:1)

您可以直接在#include <stdlib.h> #include <stdio.h> int main() { int seed; int Range; char ch = '\0'; /* initialize ch to something other than 'n' */ /* if ch not initialized, u take your chances on being able to enter while loop */ while (ch != 'n') / single quote characters, double quote for strings imply null character \0 after last character in string */ { printf("Enter a seed: "); fflush( stdout ); /* because of no \n in printf */ scanf("%d", &seed); printf("Enter a Range: "); fflush( stdout ); /* because of no \n in printf */ scanf("%d", &Range); srand(seed); for (int i = 0; i < 10; i++) { scheduler(rand() % Range + 1); } printf("Continue?\n"); /* bet u this works, because of \n */ scanf("%c", &ch); } return 0; 变量上使用date命令,如下所示。小心该命令的引用。在这里,我们根据需要将$5的命令字符串cmd形成为$5,并根据一天中的时间打印相应的%pAM

PM

关键部分在awk -v FS=, -v OFS=, '{cmd = "date -d \""$5"\" \"+%Y-%m-%d %I:%M:%S %p\""}{ cmd|getline D; close(cmd); $5=D}1' file 语句中。它强制close(cmd)每次执行awk,因此,日期将是每次实际的日期。另请参见Using getline into a Variable from a Pipe

答案 3 :(得分:0)

Orders 是一个 csv 记录文件,每条记录都有三个字段:订单号、截止日期、交货时间。我想通过从截止日期中减去提前期来计算每个订单的开始日期,将结果格式化为 dd-Mmm-yyyy,并将其附加到从订单读取的原始记录中。

awk -F, '{"date --date=\""$2" -"$3" day\" +%d-%b-%Y" | getline sd; print $1","$2","$3","sd}' orders

那么,让我们分解一下。

-F,告诉 Awk 使用逗号作为字段分隔符

'{命令 | getline 变量;command}' 是我希望 awk 对每条记录执行的操作

"date --date=""$2" -"$3" day" +%d-%b-%Y" 从日期 $2 中减去 $3 天 并将结果格式化为 dd-Mmm-yyyy。

命令 | getline 变量将命令的结果赋给变量

print $1","$2","$3","sd 打印所需的输出

结果如下

$ cat orders
order01,01-Mar-2024,1
order02,01-Jan-2021,2
$ awk -F, '{"date --date=\""$2" -"$3" day\" +%d-%b-%Y" | getline d; print $1","$2","$3","d}' orders
order01,01-Mar-2024,1,29-Feb-2024
order02,01-Jan-2021,2,30-Dec-2020