Do a tail -F until matching a pattern

后端 未结 10 1325
遥遥无期
遥遥无期 2020-11-28 09:21

I want to do a tail -F on a file until matching a pattern. I found a way using awk, but IMHO my command is not really clean. The problem is that I need to d

相关标签:
10条回答
  • 2020-11-28 09:47

    I've not results with the solution:

    sh -c 'tail -n +0 -f /tmp/foo | { sed "/EOF/ q" && kill $$ ;}'
    

    There is some issue related with the buffer because if there aren't more lines appended to the file, then sed will not read the input. So, with a little more research i came up with this:

    sed '/EOF/q' <(tail -n 0 -f /tmp/foo)
    

    The script is in https://gist.github.com/2377029

    0 讨论(0)
  • 2020-11-28 09:48
    tail -f <filename> | grep -q "<pattern>"
    
    0 讨论(0)
  • 2020-11-28 09:52

    Here's an extended version of Jon's solution which uses sed instead of grep so that the output of tail goes to stdout:

    sed -r '/EOF/q' <( exec tail -n +0 -f /tmp/foo ); kill $! 2> /dev/null
    

    This works because sed gets created before tail so $! holds the PID of tail

    The main advantage of this over the sh -c solutions is that killing a sh seems to print something to the output such as 'Terminated' which is unwelcome

    0 讨论(0)
  • 2020-11-28 09:57

    ready to use for tomcat =

    sh -c 'tail -f --pid=$$ catalina.out | { grep -i -m 1 "Server startup in" && kill $$ ;}'

    for above scenario :

    sh -c 'tail -f   --pid=$$ /tmp/foo | { grep -i -m 1 EOF && kill $$ ;}'
    
    0 讨论(0)
  • 2020-11-28 09:59

    To kill the dangling tail process as well you may execute the tail command in a (Bash) process substituion context which can later be killed as if it had been a backgrounded process. (Code taken from How to read one line from 'tail -f' through a pipeline, and then terminate?).

    : > /tmp/foo
    grep -m 1 EOF <( exec tail -f /tmp/foo ); kill $! 2> /dev/null
    echo EOF > /tmp/foo  # terminal window 2
    

    As an alternative you could use a named pipe.

    (
    : > /tmp/foo
    rm -f pidfifo
    mkfifo pidfifo
    sh -c '(tail -n +0 -f /tmp/foo & echo $! > pidfifo) | 
    { sed "/EOF/ q" && kill $(cat pidfifo) && kill $$ ;}'
    )
    
    echo EOF > /tmp/foo  # terminal window 2
    
    0 讨论(0)
  • 2020-11-28 10:07

    This is something Tcl is quite good at. If the following is "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
    

    Then you'd do tail_until.tcl /tmp/foo EOF

    0 讨论(0)
提交回复
热议问题