Take the 2-minute tour ×

When using e.g. rsync, I'd like to tee its output such that I can both view the current progress live, and have a log for later. Using just piping | tee logfile the logfile will contain many lines à la

0 files...<CR>
100 files...<CR>
200 files...<CR>

Where the carriage-return <CR> is used to have the live output replace the current line. For the stdout part of tee this is exactly the desired behavior, but is there any way to have the logfile drop anything between a <CR> and the last <LF>? (I'm not asking for a rsync specific answer, that's just the example!) Maybe some sed-piping in between?

share|improve this question
add comment

1 Answer

up vote 2 down vote accepted

You could do:

... | tee /dev/stderr | grep -v $'\r' > logfile


.... | tee >(grep -v $'\r' > logfile)

Which would effectively remove that progress line in the case of rsync. $'...' and >(...) are ksh syntax also supported by bash and zsh, but not standard sh.

share|improve this answer
The >(...) syntax (how can one even google for that?) doesn't seem to work correctly with bash - echo test >(echo) yields test /dev/fd63... But the $'...' syntax (isn't that part of grep's syntax and not *sh?) works perfecty, thanks! –  Tobias Kienzler Jan 23 '13 at 10:30
Yes, >(...) is called process substitution and is expanded by the shell to a file path. That path, when open for writing by the application (typically tee opens it, but echo doesn't) leads to a pipe whose other end is read by the command inside the brackets. You can learn about it in your shell's manual. Try man bash or info bash. –  Stephane Chazelas Jan 23 '13 at 10:34
Ah, I think now I get it. My test command causes >(echo) to run echo (yielding a newline and basically ignoring the pipe) and return /dev/fd63 such that the outer command is echo test /dev/fd63. tldp.org documents it, too. Very interesting mechanism –  Tobias Kienzler Jan 23 '13 at 11:01
side note: mingw/msys don't support process substitution and /dev/stderr doesn't exist either. At least /dev/stdout can be replaced by CON –  Tobias Kienzler Jan 24 at 9:38
add comment

Your Answer


