I'm trying to improve my shell programming skills anyway, so I made a
first pass at a program that will strip backspaces from an input file.  I
stopped short of making it robust enough to handle edits that cross
a newline; for example, the following backspaces will be left in the
output:

Here comes the end of line^H^H^H^H
line.

Here is the output from a sample input file, and the script is included
at the bottom.  I apologize for poor line wrapping; I wasn't careful to
keep the line length less than 75 when I wrote the script.  Please
comment and offer suggestions for improvement.
 
tesla:~/bin$ cat -v test.in
Now is the tame^H^H^H^Htime for all good men
to come to the help^H^H^H^Haid of their ct^Hountry.
tesla:~/bin$ cat test.in | rmbs > test.out
tesla:~/bin$ cat -v test.out
Now is the time for all good men
to come to the aid of their country.

#!/bin/sh
#
# rmbs: Remove backspaces from standard input, replacing the old characters
#       with the new, and write to standard output.  A BLATANT SHORTCOMING:
#       this script will not replace edits that cross a newline
#

# this might be a bash-ism, if it doesn't work try:  bs=`echo -n a | tr a 
'\010'`
bs=$'\010'

# This sed string matches:  zero or more non-backspace characters followed
#   by one or more backspace characters, followed by zero or more characters,
#   and replaces the entire line with the backspace characters.  Basically,
#   it outputs the first string of backspace characters to be counted with wc.

find="s/[^$bs]*\\($bs\\{1,\}\\).*/\\1/"

while read line
do
        # iteratively find strings of backspaces, because sed will only find
        # the first one on a line

        while echo "$line" | grep "$bs" > /dev/null
        do
                # count the backspaces in the first string of backspaces

                n=`echo -n "$line" | sed $find | wc -c`
                n=`expr $n`     # remove leading spaces

                # This sed string replaces the n characters before
                #   the n backspaces with the n characters following,
                #   where n is the number of backspace characters
                #   matched in the previous sed call
                # NOTE:  no replace if fewer than n characters before
                #   or after the backspace string

                replace="s/.\\{$n\\}$bs\\{$n\\}\\(.\\{$n\\}\\)/\\1/"

                line=`echo "$line" | sed $replace`
        done

        echo $line
done

----------
Marc Mongeon <[EMAIL PROTECTED]>
Unix Specialist
Ban-Koe Systems
9100 W Bloomington Fwy
Bloomington, MN 55431-2200
(612)888-0123, x417 | FAX: (612)888-3344
----------
"It's such a fine line between clever and stupid."
   -- David St. Hubbins and Nigel Tufnel of "Spinal Tap"

Reply via email to