Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

Is there a way to interpret/"execute" backspaces in a file/line using common bash commands? I have a console program which prints some stuff and than erases it using backspaces and finally writes the end result. What I actually want is the output at the end.

echo -e "Foo\b\b\bBar" | what_goes_here > test.log

My test.log should only contain "Bar". I guess a problem to do this is how much text should be buffered until considered as really printed... In my case a "line buffered" interpreter would be sufficient.

Most utility have a switch which do not print such characters in first place. But the utility at hand has no such switch...

share|improve this question
1  
I really don't know what you want to do, could you try to make it clearer ? maybe add a concrete example because is pretty confusing in my opinion –  Kiwy Apr 3 at 9:10
2  
echo -e "Foo\b\b\bBar" > test.log works for me to have only Bar in test.log. Can you elaborate why this does not work for you? –  Bernhard Apr 3 at 9:48
2  
@Bernhard Try: od -c < test.log –  Scrutinizer Apr 3 at 10:02
    
@Scrutinizer Clear, my text-editor also shows ^H –  Bernhard Apr 3 at 10:59
    
@Bernhard then your text editor "interprets" the backspaces for you. I want a clean text file, only Bar (check hexdump -C test.log) –  falstaff Apr 3 at 11:11

2 Answers 2

up vote 12 down vote accepted

That's what col -b is for:

$ printf 'a\bb\n' | col -b | od -tc
0000000   b  \n
0000002

$ printf 'aaa\b\b\bbb\n' | col -b | od -tc
0000000   b   b   a  \n
0000004

The sed equivalent would be something like:

bs=$(printf '\b')
sed "s/^[^$bs]*/&\
\
/;:1
s/\n.\{0,1\}\(.*\n\)\([^$bs]\)/\2\
\1/;s/\(.\{0,1\}\)\n\(.*\n\)$bs/\
\1\2/;t1
s/\n//g"

Dating to the times of the real tele-typewriters (tty), the x\bx sequence is sometimes found to represent a bold x (x typed over itself), x\b_ or _\bx for an underlined x (), and x\b- or -\bx for strike-through ().

Another useful command to deal with those is the colcrt command.

$ printf '_\bfo\b_o\b_ bar b\b-a\b-z\b-\n' | colcrt
foo bar baz
---

Another option is to convert \b_ and \b- to the Unicode combining characters U+0332 and U+0336:

Here assuming a Unicode locale and zsh, ksh93 or bash:

$ printf 'f\b_o\b_o\b_ bar b\b-a\b-z\b-\n' | sed $'s/\b_/\u0332/g;s/\b-/\u0336/g'
f̲o̲o̲ bar b̶a̶z̶

(pipe to colcrt or col -b to also handle the x\bx bold).

share|improve this answer
3  
+1: Had forgotten about that one :) . One would expect it to be part of POSIX, but apparently it was left out (but allowed as an "extension") on the basis that "No utilities defined in POSIX.1-2008 produce output requiring such a filter" –  Scrutinizer Apr 3 at 11:12
    
+1, great, never saw the usage cases for "col" before. –  Olivier Dulac Apr 3 at 13:27

Try sed

if used in ksh93/zsh/bash

printf "Foo\b\b\bBar\n" | sed -e :a -e "s/.\{0,1\}"$'\b'"//;ta" > test.log

or more portable

printf "Foo\b\b\bBar\n" | sed -e :a -e "s/.\{0,1\}$(printf "\b")//;ta" > test.log

or GNU sed:

printf "Foo\b\b\bBar\n" | gsed -re ":a;s/.?\x08//;ta" > test.log

Note: this approach treats '\b' as a backward erase instead of a backspace, so there would be a difference if the number of characters after a number of \b is less than the number of \b. (Thanks @StephaneChazelas )

share|improve this answer
    
This not interpreting backspaces - this is removing them via regex. –  mikeserv Apr 3 at 10:28
    
@mikeserv . Indeed, I hopefully clarified it by redirecting the examples to an output file.. –  Scrutinizer Apr 3 at 10:29
    
Yeah, I tried doing it with stty, but I can't figure it out - there are too many options and it's over my head - I know it can be done I just don't know how. Anyway, this absolutely works - and I removed my downvote. But if you can figure out to read and write the tty after it's been interpreted reliably, I'll definitely upvote. Nevermind, have one anyway. –  mikeserv Apr 3 at 11:42
2  
Note that it turns ab\b into a instead of ab. –  Stéphane Chazelas Apr 3 at 11:48
1  
col -b turns it into ab. \b doesn't delete, it moves the cursor backward. aa\b\bb should become ba. –  Stéphane Chazelas Apr 3 at 12:05

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.