【问题标题】:How to derive current date and time and append at the end of each line that contains 'Hello'如何派生当前日期和时间并附加在包含“Hello”的每一行的末尾
【发布时间】:2012-09-11 09:48:04
【问题描述】:

我有以下文件 party.txt,其中包含以下内容:

Hello Jacky
Hello Peter
Bye Johnson
Hello Willy
Bye Johnny
Hello Mary
Hello Wendy

我使用grep hello 来捕获内容,但是当我使用print date +"%Y-%m-%d' 并附加到它时,我不能,而且每行会得到很多0。

cat party.txt | grep Hello | awk '{ print date +"%Y-%m-%d"}'

我可能会错过什么?

【问题讨论】:

    标签: date awk grep


    【解决方案1】:

    一种使用awk的方式:

    awk -v date="$(date +"%Y-%m-%d %r")" '/Hello/ { print $0, date}' party.txt
    

    结果:

    Hello Jacky 2012-09-11 07:55:51 PM
    Hello Peter 2012-09-11 07:55:51 PM
    Hello Willy 2012-09-11 07:55:51 PM
    Hello Mary 2012-09-11 07:55:51 PM
    Hello Wendy 2012-09-11 07:55:51 PM
    

    请注意,日期值仅在awk启动时设置,因此不会更改,即使命令需要很长时间才能运行。

    【讨论】:

    • 如果结合danfuzz的回答,就近乎完美了。
    • 这个解决方案的问题是日期设置了一次。如果您有一个文件(或流)需要几秒钟或几分钟来解析,则每个条目都将具有完全相同的日期/时间戳。 awk 也不是支持 -v 的通用命令,nawk 是。在 Solaris 上,这不起作用,但如果您将 awk 替换为 nawk,它将起作用,您也可以使用 gawk(POSIX/GNU 兼容版本)。我更喜欢 Alin 的答案,它适用于所有 awk 实现和操作系统(前提是 awk 被 gawk 取代)
    【解决方案2】:

    gawk(和最新版本的 mawk)有一个内置的time/date function,所以不需要在那里使用外部工具。

    gawk '/Hello/{print NR " - " $0 " - " strftime("%Y-%m-%d")}' party.txt
    

    【讨论】:

    • 我要做的唯一改变是在 awk 不是 POSIX/GNU 兼容版本的操作系统上用 gawk 替换 awk。好吧,然后删除不属于原始请求的行号。
    【解决方案3】:

    要回答直接问题,您缺少的是 date 是一个外部命令,因此您需要在 awk 之外调用它并将其作为变量传递(正如其他答案之一所示),或者使用 system() 内置或管道从 awk 中作为系统命令调用它(正如另一个答案所展示的那样)。

    您看到0 的原因是因为表达式date +"%Y-%m-%d" 被解释为将变量date(它将是0,因为它未定义)的数值与字符串的数值相加"%Y-%m-%d"(将是 0,因为它不是有效的数字)。

    【讨论】:

    • 如果结合 steve 或 kent 的答案,它会接近完美。
    【解决方案4】:
     awk 'BEGIN{"date +'%Y-%m-%d'"|getline d;}/Hello/{print $0,d}' file
    

    会给你:

    Hello Jacky  2012-09-11
    Hello Peter 2012-09-11
    Hello Willy 2012-09-11
    Hello Mary 2012-09-11
    Hello Wendy 2012-09-11
    

    【讨论】:

    • 如果结合danfuzz的回答,就近乎完美了。
    【解决方案5】:

    此解决方案适用于任何 awk:

    awk '/Hello/ {cmd="(date +'%H:%M:%S')"; cmd | getline d; print d,$0; close(cmd)}' party.txt
    

    魔法发生在close(cmd) 语句中。它强制awk 每次执行cmd,因此,日期每次都是实际的。

    cmd | get line d 从cmd 读取输出并将其保存到d。

    【讨论】:

      【解决方案6】:

      如果您愿意使用 Perl:

      perl -MPOSIX -lne 'if (/Hello/){ print "$_ " . strftime "%Y-%m-%d",localtime }' party.txt
      

      产生这个输出

      Hello Jacky 2015-10-01
      Hello Peter 2015-10-01
      Hello Willy 2015-10-01
      Hello Mary 2015-10-01
      Hello Wendy 2015-10-01
      

      它是这样工作的:

      • -n循环输入文件的每一行,不要自动打印每一行

      • -l 在处理之前删除换行符,然后将它们添加回来

      • -e执行perl代码

      • $_是当前行

      • -MPOSIX 加载 POSIX 模块,其中包括 strftime

      • localtime 和 strftime 打印时间,格式为 %Y-%m-%d

      【讨论】:

        【解决方案7】:

        使用 posix sed(以及由于 sed 中缺少时间函数而导致的子 shell)

        sed -n "/^Hello/ s/$/ $( date +'%Y-%m-%d' )/p" party.txt
        

        返回

        Hello Jacky 2016-11-10
        Hello Peter 2016-11-10
        Hello Willy 2016-11-10
        Hello Mary 2016-11-10
        Hello Wendy 2016-11-10
        

        【讨论】:

          【解决方案8】:

          仅在傻瓜中:

          $ gawk '/Hello/ {print $0, strftime("%Y-%m-%d");}' party.txt 
          Hello Jacky 2019-09-17 
          Hello Peter 2019-09-17 
          Hello Willy 2019-09-17 
          Hello Mary 2019-09-17 
          Hello Wendy 2019-09-17 
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-06-23
            • 2013-05-12
            • 1970-01-01
            • 1970-01-01
            • 2016-05-13
            • 2020-05-17
            相关资源
            最近更新 更多