axelrose
axelrose

Reputation: 576

Filter function for less +F

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?

Upvotes: 19

Views: 12201

Answers (5)

Jir
Jir

Reputation: 3145

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

Upvotes: 33

Araxia
Araxia

Reputation: 1145

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

Upvotes: 2

joe
joe

Reputation: 11

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

Upvotes: 1

axelrose
axelrose

Reputation: 576

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.

Upvotes: -1

Chris May
Chris May

Reputation: 670

tail -f service.log | grep <pattern>

Upvotes: -1

Related Questions