如何取消缓冲切割?

For*_*ard 11 pipe cut

我只想从我的邮件日志文件中获取以“@xyz.nl”结尾的电子邮件地址。为了实现这一点,我这样做:

# tail -f /var/log/mail.log | grep --i --line-buffered "@xyz.nl" | cut -d '@' -f 1 | cut -d '<' -f 2
Run Code Online (Sandbox Code Playgroud)

带 grep 的 --line-buffered 是必要的,因为否则它会缓冲其输出,因为管道不被视为终端。Grep 将输出这样的行:

Aug 29 11:56:01 localhost postfix/smtp[4124]: 05491500123: to=<someone@xyz.nl>, relay=123.456.123.456[123.456.123.456]:25, delay=2, delays=0.4/0/0.4/1.2, dsn=2.0.0, status=sent (250 2.0.0 u7T9twxN074009 Message accepted for delivery)
Run Code Online (Sandbox Code Playgroud)

然后第一次切割:

Aug 29 11:56:01 localhost postfix/smtp[4124]: 05491500123: to=<someone
Run Code Online (Sandbox Code Playgroud)

第二次切割应生成:

someone
Run Code Online (Sandbox Code Playgroud)

然而,似乎 cut 也在缓冲。如果我用cat而不是tail -f启动命令,我会从日志文件中获得所有相关结果(以首选格式)。但我需要实时从日志文件中获取结果。

我尝试为此使用 unbuffer:

# tail -f /var/log/mail.log | grep --i --line-buffered "@xyz.nl" | unbuffer cut -d '@' -f 1 | cut -d '<' -f 2
Run Code Online (Sandbox Code Playgroud)

还试过:

# unbuffer tail -f /var/log/mail.log | grep --i --line-buffered "@xyz.nl" | unbuffer cut -d '@' -f 1 | cut -d '<' -f 2
Run Code Online (Sandbox Code Playgroud)

...这应该从第一次剪辑中删除 4K 缓冲。但是,这不起作用。我知道它正在缓冲,因为如果我为我们的本地域 grep 它会得到更多的命中,缓冲区会更快地填充并且输出会更早地生成(以 4K 批次)。

所以我的问题是:如何取消缓冲cut

相关:我知道 sed 和 (g)awk 可以将电子邮件地址发送给我。我一直在努力,但至今没有任何结果。欢迎使用 sed 或 (g)awk 的答案,它们可能会解决我的直接问题,但我仍然对如何取消缓冲 cut 命令的问题的名义答案感兴趣。cut 命令不涉及(取消)缓冲。

der*_*ert 22

如果您在使用 GNU Coreutils(几乎所有 Linux)的系统上,您可以尝试stdbuf

… | stdbuf -oL cut -d '@' -f 1 | …
Run Code Online (Sandbox Code Playgroud)

-oL 使其行缓冲,这似乎是您想要的。