【问题标题】:how to prefix a text with grep output如何使用 grep 输出为文本添加前缀
【发布时间】:2015-09-21 19:10:31
【问题描述】:

我想从 ABCD_ERR.LOG 读取时间 7:00:59 和 08:00:59 之间记录的日志,并在这些日志行集中搜索一些字符串并将搜索到的输出行存储到 output.txt。但我想在输出线前面加上 inputfilename ie.ABCD_ERR.LOG。 例如, ABCD_ERR.LOG 包含类似的日志

        Server 07972 006856 06:06:14.203 CleanUp - Elapsed 16 usec - Info : Session does not contain modified objects in cache.
Communications 06480 006584 07:01:56.140 Elapsed 94592 usec - Container Temperature (80)
        Server 07972 006860 07:06:20.281 Elapsed 516245941539 usec - No of resources in array = 0
Communications 06480 006584 07:11:56.140 Elapsed 92355 usec - Container Temperature (80)
        Server 07972 006860 07:16:21.296 Elapsed 516846919543 usec - No of resources in array = 0
Communications 06480 006584 07:21:56.140 Elapsed 89978 usec - Container Temperature (80)
        Server 07972 006860 07:26:22.296 CleanUpThread - Elapsed 517447899556 usec  
            BE 05452 009252 08:37:25.375 Elapsed 87 usec - Updating SESSION_ID
        Server 04616 004744 09:24:12.437 Initialize() - Elapsed 7132 usec

Regfile.txt 包含

Container Temperature
Updating SESSION_ID

以下是我正在做的事情:

grep -E "(07:[0-9][0-9]:|08:[0-9][0-9]:).*" ABCD_ERR.LOG|grep -E -f Regfile.txt > output.txt

但我希望输出(以输出行为前缀的文件名)为

ABCD_ERR.LOG:Communications 06480 006584 07:01:56.140 Elapsed 94592 usec - Container Temperature (80)
ABCD_ERR.LOG:Communications 06480 006584 07:11:56.140 Elapsed 92355 usec - Container Temperature (80)
ABCD_ERR.LOG:Communications 06480 006584 07:21:56.140 Elapsed 89978 usec - Container Temperature (80)
ABCD_ERR.LOG:       BE 05452 009252 08:37:25.375 Elapsed 87 usec - Updating SESSION_ID

有什么方法可以得到如上所示的所需输出吗? 我尝试过 /dev/null 选项,但给出错误为“grep:在标准输出上写入错误:管道正在关闭。”因为第二个 grep 的输入不是文件。 我在 Windows 7 中使用 grep

【问题讨论】:

    标签: windows grep


    【解决方案1】:

    这是 awk 的工作,而不是 grep。这将完成您所说的遇到问题(在文件名前添加):

    $ awk 'NR==FNR{re=(re?re"|":"")$0; next} /07:[0-9][0-9]:|08:[0-9][0-9]:/ && ($0 ~ re){print FILENAME":"$0}' Regfile.txt ABCD_ERR.LOG
    ABCD_ERR.LOG:Communications 06480 006584 07:01:56.140 Elapsed 94592 usec - Container Temperature (80)
    ABCD_ERR.LOG:Communications 06480 006584 07:11:56.140 Elapsed 92355 usec - Container Temperature (80)
    ABCD_ERR.LOG:Communications 06480 006584 07:21:56.140 Elapsed 89978 usec - Container Temperature (80)
    ABCD_ERR.LOG:            BE 05452 009252 08:37:25.375 Elapsed 87 usec - Updating SESSION_ID
    

    但请注意,用于识别目标范围内时间的正则表达式是错误的。这是您可以在同一天真正检查给定时间是否在给定范围内的一种方法:

    $ cat tst.awk
    (t2s($4) >= t2s("7:00:59")) && (t2s($4) <= t2s("8:00:59"))
    
    function t2s(time,      a) {
        split(time,a,/:/)
        return (((a[1] * 60) + a[2]) * 60) + a[3]
    }
    $
    $ awk -f tst.awk file
    Communications 06480 006584 07:01:56.140 Elapsed 94592 usec - Container Temperature (80)
            Server 07972 006860 07:06:20.281 Elapsed 516245941539 usec - No of resources in array = 0
    Communications 06480 006584 07:11:56.140 Elapsed 92355 usec - Container Temperature (80)
            Server 07972 006860 07:16:21.296 Elapsed 516846919543 usec - No of resources in array = 0
    Communications 06480 006584 07:21:56.140 Elapsed 89978 usec - Container Temperature (80)
            Server 07972 006860 07:26:22.296 CleanUpThread - Elapsed 517447899556 usec
    

    所以你可以结合这两个脚本来做我认为你真正想要的:

    $ cat tst.awk
    NR==FNR { re=(re?re"|":"")$0; next }
    
    ($0 ~ re) && (t2s($4) >= t2s("7:00:59")) && (t2s($4) <= t2s("8:00:59")) { print FILENAME ":" $0 }
    
    function t2s(time,      a) {
        split(time,a,/:/)
        return (((a[1] * 60) + a[2]) * 60) + a[3]
    }
    
    $ awk -f tst.awk Regfile.txt ABCD_ERR.LOG
    ABCD_ERR.LOG:Communications 06480 006584 07:01:56.140 Elapsed 94592 usec - Container Temperature (80)
    ABCD_ERR.LOG:Communications 06480 006584 07:11:56.140 Elapsed 92355 usec - Container Temperature (80)
    ABCD_ERR.LOG:Communications 06480 006584 07:21:56.140 Elapsed 89978 usec - Container Temperature (80)
    

    【讨论】:

    • 我在 Windows 中工作。 awk 是否适用于 Windows?
    • 是的,但是安装 Cygwin 会更好,因为它可以在一个窗口中为您提供类似 UNIX 的环境,然后您可以访问所有 UNIX 工具而无需处理使用 Windows 古怪的引用规则等。
    • grep 的 --label 选项是什么?我可以使用相同的前缀文件名吗?
    【解决方案2】:

    终于我的问题得到了解决 这是我用的:

    grep -E "(07:[0-5][0-9]:|08:[0-5][0-9]:).*" ABCD_ERR.LOG | grep --label=ABCD_ERR.LOG -H -E -f Regfile.txt > output.txt
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-05
      • 2019-01-13
      相关资源
      最近更新 更多