Trim the last character of a stream

Viewed 112

I use sed -e '$s/.$//' to trim the last character of a stream. Is it the correct way to do so? Are there other better ways to do so with other command line tools?

$ builtin printf 'a\nb\0' | sed -e '$s/.$//' | od -c -t x1 -Ax
000000   a  \n   b
        61  0a  62
000003

EDIT: It seems that this command is not robust. The expected output is a\nb for the following example. Better methods (but not too verbose) are needed.

$ builtin printf 'a\nb\n' | sed -e '$s/.$//' | od -c -t x1 -Ax
000000   a  \n  \n
        61  0a  0a
000003
2 Answers

You may use head -c -1:

printf 'a\nb\0' | head -c -1 | od -c -t x1 -Ax

000000   a  \n   b
        61  0a  62
000003


printf 'a\nb\n' | head -c -1 | od -c -t x1 -Ax

000000   a  \n   b
        61  0a  62
000003

It seems you can't rely on any line-oriented tools (like sed) that automatically remove and re-add newlines.

Perl can slurp the whole stream into a string and can remove the last char:

$ printf 'a\nb\0' | perl -0777 -pe chop  | od -c -t x1 -Ax
000000   a  \n   b
        61  0a  62
000003

$ printf 'a\nb\n' | perl -0777 -pe chop  | od -c -t x1 -Ax
000000   a  \n   b
        61  0a  62
000003

The tradeoff is that you need to hold the entire stream in memory.

Related