Re: script command question
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 <mongeon@bankoe.com>
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 to: