做尾巴-F直到匹配模式

Sam*_*lba 22 shell awk sed tcl tail

我想在文件上做一个尾部-F,直到匹配一个模式.我找到了一种使用awk的方法,但恕我直言,我的命令并不是很干净.问题是我需要在一行中完成,因为有一些限制.

tail -n +0 -F /tmp/foo | \
awk -W interactive '{if ($1 == "EOF") exit; print} END {system("echo EOF >> /tmp/foo")}'
Run Code Online (Sandbox Code Playgroud)

尾部将阻塞,直到EOF出现在文件中.它工作得很好.END块是强制性的,因为awk的"退出"不会立即退出.在退出之前使awk评估END块.END块在读取调用时挂起(因为尾部),所以我需要做的最后一件事就是在文件中写入另一行来强制尾部退出.

有人知道更好的方法吗?

Gre*_*ett 35

使用tail的--pid选项,当shell死亡时,tail将停止.无需在tailed文件中添加额外内容.

sh -c 'tail -n +0 --pid=$$ -f /tmp/foo | { sed "/EOF/ q" && kill $$ ;}'
Run Code Online (Sandbox Code Playgroud)

  • 如果你的尾部不支持 `--pid` 选项,你可以使用 `sh -i -c 'tail -n +0 -f /tmp/foo | { sed "/EOF/ q" && kill 0 ;}'`. _sh -i_ 创建一个新的进程组,`kill 0` 会杀死当前进程组中的所有进程。 (2认同)

jpe*_*zzo 29

试试这个:

sh -c 'tail -n +0 -f /tmp/foo | { sed "/EOF/ q" && kill $$ ;}'
Run Code Online (Sandbox Code Playgroud)

只要在/ tmp/foo中看到"EOF"字符串,整个命令行就会退出.

有一个副作用:尾部进程将保持运行(在后台),直到将任何内容写入/ tmp/foo.


小智 8

我没有解决方案的结果:

sh -c 'tail -n +0 -f /tmp/foo | { sed "/EOF/ q" && kill $$ ;}'
Run Code Online (Sandbox Code Playgroud)

有一些与缓冲区有关的问题,因为如果没有更多的行附加到文件,那么sed将不会读取输入.所以,通过更多的研究我想出了这个:

sed '/EOF/q' <(tail -n 0 -f /tmp/foo)
Run Code Online (Sandbox Code Playgroud)

该脚本位于https://gist.github.com/2377029


gle*_*man 5

这是 Tcl 非常擅长的事情。如果下面是“tail_until.tcl”,

#!/usr/bin/env tclsh

proc main {filename pattern} {
    set pipe [open "| tail -n +0 -F $filename"]
    set pid [pid $pipe]
    fileevent $pipe readable [list handler $pipe $pattern]
    vwait ::until_found
    catch {exec kill $pid}
}

proc handler {pipe pattern} {
    if {[gets $pipe line] == -1} {
        if {[eof $pipe]} {
            set ::until_found 1
        }
    } else {
        puts $line
        if {[string first $pattern $line] != -1} {
            set ::until_found 1
        }
    }
}

main {*}$argv
Run Code Online (Sandbox Code Playgroud)

那么你会做 tail_until.tcl /tmp/foo EOF