[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

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: