pol*_*lym 8 shell grep io-redirection tee
我正在使用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>
Run Code Online (Sandbox Code Playgroud)
XXX.XXX.XX.XXX
这是一个 IP 地址,随机文本是错误消息。遗憾的是,所有输出都指向标准输出。
如何将所有以 IP 地址开头的行定向到名为的文件,err.log
并将每隔一行定向到all.log
?
不幸的是,gradle run
它只能启动一次并且不能停止,因为它是一个 REST 服务器。
也许使用tee
,grep
组合?
在 Bash 中,您可以使用带有 tee 的进程替换:
tee >(grep XXX > err.log) | grep -v XXX > all.log
Run Code Online (Sandbox Code Playgroud)
这会将与 XXX 匹配的所有行放入err.log
,并将所有行放入all.log
. >( ... )
在括号中创建进程并将其标准输出连接到管道。这也适用于zsh和其他现代 shell。
您还可以使用pee
来自moreutils的命令:
pee "grep XXX > err.log" "grep -v XXX > all.log"
Run Code Online (Sandbox Code Playgroud)
pee
将标准输入重定向到多个命令(“管道 tee”)。
另一种选择是使用 awk:
awk '{ if (/^([0-9]{1,3}\.){3}[0-9]{1,3}/) { print > "err.log" } else { print > "all.log" } }'
Run Code Online (Sandbox Code Playgroud)
这只是针对表达式测试每一行,err.log
如果匹配,all.log
如果不匹配,则将整个内容写入。
awk 正则表达式也适用于grep -E
(虽然它确实匹配了一些错误的地址——999.0.0.0
等等——但这可能不是问题)。