5

I'm looking for a 1 liner to tail a file and grep a "string", print the first match (new line) and exit.

I came up with:

tail -f /var/log/logfile.log -n 0 | grep -m 1 -i string_to_match

actual result is that the command prints the first match but exits only after the second match. any help would be appreciated

tripleee
  • 175,061
  • 34
  • 275
  • 318
Isaac A
  • 93
  • 1
  • 8
  • See this: https://stackoverflow.com/questions/5024357/do-a-tail-f-until-matching-a-pattern which also has a link to Superuser with more solutions. – James Brown Jan 01 '19 at 09:42
  • 2
    Heh. So, `grep` exits immediately, but `tail` doesn't *know* that `grep` exited until it tries to write a second line and gets a SIGPIPE. – Charles Duffy Jan 01 '19 at 16:17

1 Answers1

7

In Bash you could use:

$ grep -m 1 string_to_match <(tail -n 0 -f file)

This could work for testing (NOTICE: IT APPENDS TO A FILE NAMED file):

$ grep -m 1 foo <(tail -n 0 -f file) & sleep 2 ; echo -e bar\\nfoo >> file
[1] 5390
foo
[1]+  Done                    grep --color -m 1 foo <(tail -n 0 -f file)

Edit: Further testing revealed that tail stays running in the background but exits after the next line in the file.

James Brown
  • 36,089
  • 7
  • 43
  • 59
  • Humm, pretty hard to make a one-liner for testing. – James Brown Jan 01 '19 at 09:11
  • thanks, this one gives syntax error near unexpected token `(' – Isaac A Jan 01 '19 at 09:13
  • 1
    @IsaacA: You don't use `bash`. – Cyrus Jan 01 '19 at 09:15
  • @Cyrus GNU bash, version 3.2.57(1)-release – Isaac A Jan 01 '19 at 09:25
  • @Tiw cant use perl :( – Isaac A Jan 01 '19 at 09:28
  • @Cyrus Ive edited your suggestion to: grep -m 1 urlfilter <$(tail -n 0 -f /var/log/alert1.log) but it does not print and does not exits... just sits there.... – Isaac A Jan 01 '19 at 09:44
  • 1
    @IsaacA: I can't reproduce the error you mentioned with [bash-3.2.57](http://ftp.gnu.org/gnu/bash/bash-3.2.57.tar.gz). It occurs when using `sh`. – Cyrus Jan 01 '19 at 09:52
  • If targeting a new enough version of bash, command substitutions' PIDs will be put in `$!` so you can kill them explicitly, so don't need to wait for the later match/exit. I want to say that's version 4.3 or therebouts. – Charles Duffy Jan 01 '19 at 16:18
  • 2
    @JamesBrown Eventually what you suggested was the right answer for me! Thanks and thank you all! grep -m 1 string_to_match <(tail -n 0 -f /var/log/syslog.log) – Isaac A Jan 02 '19 at 08:03