Filter function for less +F
Asked Answered
S

5

19

When watching a growing log file with e.g. "less -iS +F service.log" I want to limit the display to lines matching a certain pattern.

I tried something like

less +F service.log | grep <pattern> | less +F

which doesn't work. Also

cat < service.log | grep <pattern> | less +F

doesn't do what I want. It looks like the input is already closed and less doesn't show changes.

How can I limit the display to lines matching a certain pattern?

Shortridge answered 19/11, 2009 at 9:7 Comment(0)
A
32

This question is ages old, but I still think it's worth adding a solution. Instead of trying to grep first and then use less, what about using filtering inside less?

In brief:

  1. use less +F on your file
  2. CTRL-C to temporarily break the "following" action
  3. Type & and your pattern to enable filtering
  4. Issue +F to re-enable the "following" action

More details on this answer on the Unix&Linux StackExchange

Aplomb answered 13/5, 2019 at 10:16 Comment(2)
To do this directly from the command line: less '+&<pattern>^MF' service.log where the ^M is obtained by typing ctrl-v and then enterMattie
From bash, without the C-v (quoted-insert): less $'+&<pattern>\nF' service.logWash
S
2

I haven't yet worked out how to do this without a temp file, but here is a script that demonstrates a functional grep-filtered less +F (which cleans up its temp file). I call it lessf.

One of the key elements is the --line-buffered argument to grep that permits tail output to continue to flow through the pipeline (the unbuffer command provided by expect provides similar functionality for any program).

#!/bin/sh
LOGFILE=$1
shift
PATTERN=$@
TEMP_DIR=/tmp/lesstmp
TEMP_FILE="$TEMP_DIR/$(basename $LOGFILE)"
[ ! -d $TEMP_DIR ] && mkdir $TEMP_DIR
trap 'rm -rf "$TEMP_DIR"; exit' INT TERM EXIT
( tail -f "$LOGFILE" | grep --line-buffered $PATTERN ) > "$TEMP_FILE" | less +F "$TEMP_FILE"
trap - INT TERM EXIT

Example usage:

lessf /var/log/system.log foobar

lessf /var/log/system.log -v nobar

Skylab answered 29/12, 2011 at 2:6 Comment(1)
I'd like to point out how using the pipe between tail|grep and less +F makes sure that Ctrl-C will kill them all in one go. I had something similar but using background jobs, it doesn't work as well.Lajuanalake
L
1

If you don't mind spawning and tearing down a couple of processes each line, use a read while loop

tail -f filename.log|while read line; do echo $line | grep pattern; done
Larimore answered 11/8, 2011 at 16:10 Comment(0)
T
-1
tail -f service.log | grep <pattern>
Tipton answered 19/11, 2009 at 11:15 Comment(1)
Thanks for pondering my question though this is not exactly what I want. I want to have "less" functionality, i.e. scrolling, searching, hightlighting within the resulting output. Something like "tail -f service.log | grep <pattern> | less +F" which unfortunalely doesn't do it.Shortridge
S
-1

The solution seemed simply

LESSOPEN='|grep <pattern> %s' less +F service.log

but less doesn't continue to read new lines from the growing log file.

Shortridge answered 20/11, 2009 at 12:53 Comment(1)
my original answer from 2009 doesn't seem to be valid anymore, i.e. the simple solution does watch for a growing log fileShortridge

© 2022 - 2024 — McMap. All rights reserved.