V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Distributions
Ubuntu
Fedora
CentOS
中文资源站
网易开源镜像站
lengjian
V2EX  ›  Linux

awk 如何输出到文件

  •  
  •   lengjian · 2022-05-19 23:58:01 +08:00 · 2068 次点击
    这是一个创建于 679 天前的主题,其中的信息可能已经有所发展或是发生改变。

    abc.log 中不断产生日志,想持续统计上一秒该日志文件记录下含有'发送'关键字的数量,已经用以下脚本实现了,

    tail -f /var/logs/abc.log | grep '发送' | awk 'BEGIN{FS="." } {if($1==tmp) {count[tmp]++;} else { print tmp, "\t"count[tmp]} tmp=$1;}'
    

    以下是终端输出内容

    2022-05-19 23:49:55 	8
    2022-05-19 23:49:56 	6
    2022-05-19 23:49:57 	8
    2022-05-19 23:49:58 	3
    2022-05-19 23:49:59 	6
    2022-05-19 23:50:00 	5
    

    现在想把结果输出到文件中,请教 awk 内该怎么修改或者更好的办法达到目的

    第 1 条附言  ·  2022-05-20 09:41:34 +08:00

    abc.log 中持续日志如下格式

    2022-05-20 09:38:17.649  INFO 5407 --- [ntLoopGroup-6-5] c.y.s.d.netty.handler.DeviceMsgEncoder   : 发送 XXXX
    2022-05-20 09:38:17.650  INFO 5407 --- [ntLoopGroup-6-5] c.y.s.d.netty.handler.DeviceMsgEncoder   : 处理 XX
    
    17 条回复    2022-05-20 14:58:34 +08:00
    DCCooper
        1
    DCCooper  
       2022-05-20 00:21:01 +08:00 via iPhone
    >
    herich
        2
    herich  
       2022-05-20 00:31:31 +08:00 via Android
    也可以了解一下 tee
    luckyrayyy
        3
    luckyrayyy  
       2022-05-20 00:34:30 +08:00
    >>
    sora2blue
        4
    sora2blue  
       2022-05-20 00:38:07 +08:00
    加个 | tee 同时输出到文件和终端
    thedrwu
        5
    thedrwu  
       2022-05-20 07:21:59 +08:00 via Android
    grep ‘发送’ 可以直接放到 awk 里 /发送 /{…}
    justrand
        6
    justrand  
       2022-05-20 08:40:13 +08:00
    > 1.txt
    nyfwan123
        7
    nyfwan123  
       2022-05-20 08:45:33 +08:00
    99 八十一难
    眼看到灵山脚下了
    你就差个>
    不应该啊。。。。
    huntagain2008
        8
    huntagain2008  
       2022-05-20 09:07:27 +08:00
    小白的看法,楼主的意思是在 awk 内部 输出到文件, 比如
    [jerry]$ awk 'BEGIN { print "Hello, World !!!" > "/tmp/message.txt" }'

    楼上的应该说的是在后面重定向输出到文件
    tail -f /var/logs/abc.log | grep '发送' | awk 'BEGIN{FS="." } {if($1==tmp) {count[tmp]++;} else { print tmp, "\t"count[tmp]} tmp=$1;}' >output
    或者同时输出到文件和终端
    tail -f /var/logs/abc.log | grep '发送' | awk 'BEGIN{FS="." } {if($1==tmp) {count[tmp]++;} else { print tmp, "\t"count[tmp]} tmp=$1;}' | tee output
    Davic1
        9
    Davic1  
       2022-05-20 09:07:53 +08:00
    @nyfwan123 哈哈哈哈哈哈, 只渡有缘人.
    lengjian
        10
    lengjian  
    OP
       2022-05-20 09:37:25 +08:00
    @DCCooper
    @luckyrayyy
    @sora2blue
    @justrand
    @nyfwan123
    @huntagain2008

    试了以下几种方式,输出文件内容总是 0 ,文件内没有任何内容,并且终端也不再有输出内容了

    ```bash
    # >
    tail -f //var/logs/abc.log | grep '发送' | awk 'BEGIN{FS="." } {if($1==tmp) {count[tmp]++;} else { print tmp, "\t"count[tmp] > output} tmp=$1;}'
    # >>
    tail -f /var/logs/abc.log | grep '发送' | awk 'BEGIN{FS="." } {if($1==tmp) {count[tmp]++;} else { print tmp, "\t"count[tmp] >> output} tmp=$1;}'


    tail -f /var/logs/abc.log | grep '发送' | awk 'BEGIN{FS="." } {if($1==tmp) {count[tmp]++;} else { print tmp, "\t"count[tmp]} tmp=$1;}' >output

    # tee
    tail -f /var/logs/abc.log | grep '发送' | awk 'BEGIN{FS="." } {if($1==tmp) {count[tmp]++;} else { print tmp, "\t"count[tmp]} tmp=$1;}' | tee output
    ```
    huntagain2008
        11
    huntagain2008  
       2022-05-20 09:50:23 +08:00
    #10 小白的看法,也许是 grep 的原因,改成
    awk '/发送 / {...}'
    lengjian
        12
    lengjian  
    OP
       2022-05-20 10:05:11 +08:00
    @huntagain2008
    改成如下
    tail -f /var/logs/abc.log | awk 'BEGIN{FS="." } {if($1==tmp && /发送 /) {count[tmp]++;} else { print tmp, "\t"count[tmp]} tmp=$1;}' | tee output

    然后终端与 output 文件都有输出了,但结果并不是想要的
    ```bash
    2022-05-20 10:01:53
    2022-05-20 10:01:53
    2022-05-20 10:01:53
    2022-05-20 10:01:53 1
    2022-05-20 10:01:53 1
    2022-05-20 10:01:53 1
    2022-05-20 10:01:53 1
    2022-05-20 10:01:53 2
    2022-05-20 10:01:54
    2022-05-20 10:01:54
    2022-05-20 10:01:54
    2022-05-20 10:01:54 1
    2022-05-20 10:01:54 1
    2022-05-20 10:01:54 1
    2022-05-20 10:01:54 1
    2022-05-20 10:01:54 2
    2022-05-20 10:01:54 2
    2022-05-20 10:01:54 2
    2022-05-20 10:01:54 2
    2022-05-20 10:01:54 3
    2022-05-20 10:01:54 3
    2022-05-20 10:01:54 3
    2022-05-20 10:01:54 3
    2022-05-20 10:01:54 4
    2022-05-20 10:01:54 4
    2022-05-20 10:01:54 4
    2022-05-20 10:01:54 4
    2022-05-20 10:01:54 4
    2022-05-20 10:01:54 5
    2022-05-20 10:01:54 5
    2022-05-20 10:01:54 5
    2022-05-20 10:01:54 5
    2022-05-20 10:01:54 6
    2022-05-20 10:01:54 6
    2022-05-20 10:01:54 6
    2022-05-20 10:01:54 6
    2022-05-20 10:01:54 7
    2022-05-20 10:01:55
    2022-05-20 10:01:55
    2022-05-20 10:01:55
    2022-05-20 10:01:55 1
    2022-05-20 10:01:55 1
    2022-05-20 10:01:55 1
    2022-05-20 10:01:55 1
    2022-05-20 10:01:55 2
    2022-05-20 10:01:55 2
    2022-05-20 10:01:55 2
    2022-05-20 10:01:55 2
    2022-05-20 10:01:55 3
    2022-05-20 10:01:55 3
    2022-05-20 10:01:55 3
    2022-05-20 10:01:55 3
    2022-05-20 10:01:55 4
    2022-05-20 10:01:55 4
    2022-05-20 10:01:55 4
    2022-05-20 10:01:55 4
    2022-05-20 10:01:55 5
    2022-05-20 10:01:56
    2022-05-20 10:01:56
    2022-05-20 10:01:56
    2022-05-20 10:01:56 1
    2022-05-20 10:01:56 1
    2022-05-20 10:01:56 1
    2022-05-20 10:01:56 1
    2022-05-20 10:01:56 2
    2022-05-20 10:01:56 2
    2022-05-20 10:01:56 2
    2022-05-20 10:01:56 2
    2022-05-20 10:01:56 3
    2022-05-20 10:01:56 3
    2022-05-20 10:01:56 3
    2022-05-20 10:01:56 3
    2022-05-20 10:01:56 4
    2022-05-20 10:01:56 4
    2022-05-20 10:01:56 4
    2022-05-20 10:01:56 4
    2022-05-20 10:01:56 5
    2022-05-20 10:01:56 5
    2022-05-20 10:01:56 5
    2022-05-20 10:01:56 5
    2022-05-20 10:01:56 6
    2022-05-20 10:01:56 6
    2022-05-20 10:01:56 6
    2022-05-20 10:01:56 6
    2022-05-20 10:01:56 7
    ```

    想要的是统计上一秒的日志输出中含有指定关键字的条目数
    jaredyam
        13
    jaredyam  
       2022-05-20 11:37:22 +08:00
    @lengjian #12

    试试?(你这个命令在我的 macOS 上无法跑通,需要使用 stdbuf --output=L 强制 stdout 为 line buffered ,以上 grep 无法跑通同理)
    > tail -f /var/logs/abc.log | awk 'BEGIN{FS="." } {if($1==tmp && /发送 /) {count[tmp]++;} else { print tmp, "\t"count[tmp]} tmp=$1;}' | tee output

    tail -f /var/logs/abc.log | awk -F. '/发送 / { if($1==tmp) { count[tmp]++; } else { print tmp"\t"count[tmp] }; tmp=$1; }' | tee output
    lengjian
        14
    lengjian  
    OP
       2022-05-20 11:50:43 +08:00
    @jaredyam CentOS7 上跑的,macOS 上没有试

    tail -f /var/logs/abc.log | awk -F. '/发送 / { if($1==tmp) { count[tmp]++; } else { print tmp"\t"count[tmp] }; tmp=$1; }' | tee output
    这条命令运行同 10#,也是终端、文件都没输出
    jaredyam
        15
    jaredyam  
       2022-05-20 12:23:07 +08:00
    @lengjian #14

    按照我在 #13 说的,在 awk 前加 stdbuf --output=L 试试?
    lindas
        16
    lindas  
       2022-05-20 14:02:41 +08:00
    应该是缓冲的问题,试一下 tail -f access.log |grep --line-buffered '128' | awk '{print $1};system("")' > output.file
    grep 加 --line-buffered
    awk 加 system("")
    lengjian
        17
    lengjian  
    OP
       2022-05-20 14:58:34 +08:00
    @jaredyam
    @lindas
    感谢!两种方法都 ok

    ```bash
    tail -f /var/logs/abc.log | stdbuf --output=L awk -F. '/发送 / {if($1==tmp) {count[tmp]++;} else { print tmp, "\t"count[tmp]} tmp=$1;}' | tee output

    tail -f /var/logs/abc.log | grep '发送' | stdbuf --output=L awk -F. '{if($1==tmp) {count[tmp]++;} else { print tmp, "\t"count[tmp]} tmp=$1;}' | tee output

    tail -f /var/logs/abc.log | grep --line-buffered '发送' | awk 'BEGIN{FS="." } {if($1==tmp) {count[tmp]++;} else { print tmp, "\t"count[tmp]} tmp=$1;} system("")' | tee output
    ```
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3572 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 04:57 · PVG 12:57 · LAX 21:57 · JFK 00:57
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.