Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to read unbuffered input of lines ending with "\r" or "\n"?

Tags:

io

stdin

perl

I'm writing a simple program which is intended to filter input from a pipeline. Most of the input is sent as output untouched. Part of it is modified or used to extract information. In its simplest form — doing nothing — the program filter is:

$|++;

while (<>) {
    print;
}

The main program sometimes outputs progress updates of its task, overwriting the same visual content through the use of lines ending with a carriage return. Piping such content to filter blocks all output:

$ perl -e '$|++; print ++$a, "\r" and sleep 1 while 1' | filter

Is there an easy way to read those lines in the same loop fashion, or should I go the sysread way? I'm looking for something similar to what would happen if it was possible to set the record separator to "\n or \r".

like image 701
sidyll Avatar asked Dec 20 '18 19:12

sidyll


1 Answers

If the input isn't so large that efficiency is a concern, this version of filter is more robust

while (!eof(STDIN)) {
    $_ .= getc(STDIN);
    if (/[\r\n]/) {
        # manipulate $_, if desired
        print;
        $_ = "";
    }
}
print;
like image 157
mob Avatar answered Nov 10 '22 22:11

mob