【问题标题】:Split log file using a column with awk or sed使用带有 awk 或 sed 的列拆分日志文件
【发布时间】:2012-11-28 14:36:09
【问题描述】:

我有一个如下所示的日志文件:

www.domainone.com FIX 3.3 12.12.123.1
www.domainone.com FIX 3.4 12.12.123.1
www.domainone.com FIX 2.4 12.12.123.1
www.domaintwo.com MAX 1.4 44.15.153.5
www.domaintwo.com MAX 3.2 44.15.153.5
www.domaintwo.com MAX 3.9 44.15.153.5
www.domaintwo.com MAX 12.4 44.15.153.5
www.domainthree.com NAN 3.4 34.45.144.7
www.domainthree.com NAN 2.4 34.45.144.7
www.domainthree.com NAN 3.2 34.45.144.7
www.domainthree.com NAN 3.3 34.45.144.7
www.domainthree.com NAN 1.4 34.45.144.7

我想运行一个 grep、awk、sed 或其他 bash 命令/脚本,该命令/脚本将按最后一列拆分该日志文件,因此结果是 3 个使用 IP 命名的日志文件,不带点。所以,其中之一是 34.45.144.7.log 并且有

www.domainthree.com NAN 3.4 34.45.144.7
www.domainthree.com NAN 2.4 34.45.144.7
www.domainthree.com NAN 3.2 34.45.144.7
www.domainthree.com NAN 3.3 34.45.144.7
www.domainthree.com NAN 1.4 34.45.144.7

我能够使用 awk 对它们进行排序并从原始日志中删除一些列,但不知道如何使用一列拆分为文件。

【问题讨论】:

    标签: bash logging awk sed


    【解决方案1】:

    如果IP总是第四列,你可以直接使用

    awk '{ filename=$4".log"; if (prev && (filename != prev)) close(prev); print >>filename; prev=filename }' ips.log
    

    或者根据@Ed Morton 的说法,甚至更好

    awk '{ print >>($4".log"); close($4".log") }' ips.log
    

    这会将整行打印到由第四列(IP)+“.log”组成的文件中

    这是 Ubuntu 12.04 和 GNU awk 3.1.8。

    【讨论】:

    • 得到了 awk:源代码第 1 行的语法错误,上下文是 {print >>> >$4".log"
    • 删除“>”时没有收到错误消息,但它不会打印到其他文件。另外,如前所述,我需要 3 个文件,包含所有行,基于 IP。
    • @iwek 你用什么操作系统和awk?
    • 我有一个 MAC OSX 10.6.8,但如果需要我可以运行 Ubuntu。更重要的是,我需要 3 个文件,因为有 3 个不同的 IP 地址,每个文件都需要包含所有行,而不仅仅是 IP 地址。
    • 我看到你编辑了它,它很接近,但我的意思是awk '{filename=$4".log"; if (filename != prev) close(prev); print >filename; prev=filename }' ips.log。照原样失败,因为它仅针对 $4 而不是 $4".log" 测试文件名。
    【解决方案2】:

    所以结果是 3 个使用 IP 命名的日志文件没有 点

    awk '{f=$4; gsub(/\./,"",f);print > f".log"}' ips.log
    

    【讨论】:

    • 得到 awk:源代码行 1 的语法错误,上下文为 {f=$4; gsub(/\./,"",f);打印 > >>> f".log"
    • 问题是 ">" 在 awk 脚本中。
    • 感谢您。这是一个 OSX 错误。但是你确实忘记了全局。在 OSX 中,这有效: awk '{filename = gsub(/\./g,"",$4)".log";打印 > 文件名}' test.log
    • 不一定是错误。当您执行print > $4 ".log" 时,这意味着(print > $4) ".log" 还是print > ($4 ".log")?答案是它是模棱两可的,所以你应该根据需要加括号。在这种情况下,你应该写print > ($4 ".log")
    【解决方案3】:

    应@OlafDietsche 的要求:

    awk '{ filename=$4".log"; if (filename != prev) close(prev); print >filename; prev=filename }' ips.log
    

    没想到 cmets 拖了这么久,否则我早就干了!

    【讨论】:

      猜你喜欢
      • 2017-08-25
      • 2018-08-20
      • 1970-01-01
      • 1970-01-01
      • 2012-07-11
      • 2012-04-30
      • 1970-01-01
      • 2012-05-22
      • 1970-01-01
      相关资源
      最近更新 更多