根据 grep 正则表达式重定向输出

根据 grep 正则表达式重定向输出

我用来gradle run启动 REST 服务器。 REST 服务器的输出如下所示:

XXX.XXX.XX.XXX - <moreinfo>
randomtext
randomtext
XXX.XXX.XX.XXX - <moreinfo>
XXX.XXX.XX.XXX - <moreinfo>
randomtext
XXX.XXX.XX.XXX - <moreinfo>

XXX.XXX.XX.XXX这是 IP 地址,随机文本是错误消息。遗憾的是,所有输出都定向到标准输出。

如何将所有以 IP 地址开头的行定向到名为 的文件,err.log并将每隔一行定向到all.log

不幸的是,gradle run只能启动一次并且不能停止,因为它是 REST 服务器。

也许使用tee,grep组合?

答案1

在 Bash 中,您可以使用流程替代带 T 恤:

tee >(grep XXX > err.log) | grep -v XXX > all.log

这会将所有匹配 XXX 的行放入err.log,并将所有行放入all.log>( ... )在括号中创建进程并将其标准输出连接到管道。这适用于还有其他现代贝壳。

您还可以使用以下pee命令更多实用程序:

pee "grep XXX > err.log" "grep -v XXX > all.log"

pee将标准输入重定向到多个命令(“管道的三通”)。

另一种选择是使用 awk:

awk '{ if (/^([0-9]{1,3}\.){3}[0-9]{1,3}/) { print > "err.log" } else { print > "all.log" } }'

这只是针对表达式测试每一行,并将整个内容写入err.log是否匹配或all.log不匹配。

awk 正则表达式也适合grep -E(尽管它确实匹配一些错误的地址 -999.0.0.0等等 - 但这可能不是问题)。

答案2

因此,它看起来gradle run不符合teepeegrepio 重定向。它总是在 4096 字节后停止读取。

为了避免这个问题,我read将每一行gradle run.我还没有测试过,但我猜读取超过 4k 个字符长的行也会失败。

无论如何,这是专门解决我的问题的代码:

#!/bin/bash
STDOUTLOG="/log/stdout.txt"
STDERRLOG="/log/stderr.txt"
while read -r line; do
    [[ $line =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}.* ]] && printf '%s\n' "$line" >> "$STDERRLOG" && continue
    printf '%s\n' "$line" >> "$STDOUTLOG"
done < <(gradle run)

相关内容