brunocodutra
brunocodutra

Reputation: 2349

Interactively piping through grep

I have a script which takes fairly long to execute. Throughout the process, it is continuously outputing to stdout. I would like to have some of these mesages interactively displayed in some sort of progress dialog using a graphical utility like kdialog or zenity for instance, but that's not relevant here, for the solution I seek should not depend on it.

To accomplish this I'm trying the following

<call to actual job> | egrep <regex> | xargs -I{} <call to display utility> {}

The problem is that once I insert the call to egrep the output is sort of accumulated untill the main job finishes, before it is effectively piped on to xargs. If I take egrep out, then it works as expected and the status mesages are interactively piped on to xargs, but then a lot of irelevant information is displayed.

I've been searching all over the internet and reading the manual for grep to no avail, does anyone know how I could achieve the desired behavior?

Practical Example

I believe the following example behaves analogously to my real case.

(sleep 1; echo A; sleep 1; echo 0; sleep 1; echo B) | egrep -i [a-z] | xargs -I{} echo {}

Upvotes: 0

Views: 155

Answers (2)

brunocodutra
brunocodutra

Reputation: 2349

Meanwhile I found the exact answer this question: grep and its variations have an option to force flushing line by line.

man is not very helpful

--line-buffered Use line buffering on output. This can cause a performance penalty.

that's why I overlooked this option at first.

Fortunately grep --help makes it more obvious.

--line-buffered flush output on every line

Upvotes: 0

konsolebox
konsolebox

Reputation: 75478

Try to use a less buffered command. I'm not sure about awk but you could do this with it:

<call to actual job> | awk '/regex/' | xargs -I{} <call to display utility> {}

Another with sed:

<call to actual job> | sed -n '/regex/p' | xargs -I{} <call to display utility> {}

And my favorite for that actually would be bash:

function filter {
    while read -r __; do
        [[ $__ =~ $1 ]] && echo "$__"
    done
}

<call to actual job> | filter "<regex>" | xargs -I{} <call to display utility> {}

It's could be a little slower but it certainly doesn't buffer output much.

Upvotes: 2

Related Questions