Search code examples
bashpipecarriage-return

pipe a command not printing newline (but using \r)


I want to pipe the output of a program that doesn't print newline, as it uses carriage return to replace it's line with new content.

this code represents the behavior of the program I'd like to retreive the output.

#!/usr/bin/env bash                                                             

for i in {1..100};do                                                            
    echo -ne "[ $i% ] long unneeded log\r"                                            
    sleep 0.3                                                                   
done

i'd like , in a bash script, to cut this output live to display only the important info, but as the program doesn't prints newline a ./program | awk ... shows the output only when the command is ended.

I cannot modify the program that gives this output I'm trying to trim. (I don't have it's source + I want to share my own script with other users)

I know my request is pretty specific, but is there a way to pipe the output character by character instead that by line?


Solution

  • I found it thanks to a mix of @OznOg answer and @Walter-A link.

    indeed replacing carriage returns with newline with tr works, but it is buffered by default, stdbuf can unbuffer it with stdbuf -o0.

    so the final command is:

    ./program | stdbuf -o0 tr '\r' '\n' |  awk -F'[][]' '{printf $2 "\r"}'
    

    this indeed prints live the first match between brackets, with a carriage return.

    so a live log from the program showing on a single updated line [x%] long compile detail would be abbreviated just to x%, still using 1 line.