awk 如何输出到文件

2022-05-19 23:58:01 +08:00
 lengjian

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 内该怎么修改或者更好的办法达到目的

2088 次点击
所在节点    Linux
17 条回复
DCCooper
2022-05-20 00:21:01 +08:00
>
herich
2022-05-20 00:31:31 +08:00
也可以了解一下 tee
luckyrayyy
2022-05-20 00:34:30 +08:00
>>
sora2blue
2022-05-20 00:38:07 +08:00
加个 | tee 同时输出到文件和终端
thedrwu
2022-05-20 07:21:59 +08:00
grep ‘发送’ 可以直接放到 awk 里 /发送 /{…}
justrand
2022-05-20 08:40:13 +08:00
> 1.txt
nyfwan123
2022-05-20 08:45:33 +08:00
99 八十一难
眼看到灵山脚下了
你就差个>
不应该啊。。。。
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
2022-05-20 09:07:53 +08:00
@nyfwan123 哈哈哈哈哈哈, 只渡有缘人.
lengjian
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
2022-05-20 09:50:23 +08:00
#10 小白的看法,也许是 grep 的原因,改成
awk '/发送 / {...}'
lengjian
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
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
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
2022-05-20 12:23:07 +08:00
@lengjian #14

按照我在 #13 说的,在 awk 前加 stdbuf --output=L 试试?
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
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
```

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/854036

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX