26 Shpell: An Interactive Spell-Checking Facility


#26 Shpell : An Interactive Spell-Checking Facility

Checking the spelling of something word by word is useful, but more commonly you'll want to check all of the words in a file en masse. You can do that with ispell , if you've installed it, but ispell has an interface that some people find baffling. And if you don't have ispell , many of the more rudimentary spell-checking packages don't offer much more sophistication than simple "Is this word right?" functionality. Therefore, in either case, an alternative approach to checking and fixing all of the spelling errors throughout a file might be just what you need, and it's easily accomplished with this shell script.

The Code

 #!/bin/sh # shpell - An interactive spell-checking program that lets you step #   through all known spelling errors in a document, indicate which #   ones you'd like to fix and how, and apply the changes to the file #   The original version of the file is saved with a .shp suffix, #   and the new version replaces the old. # # Note that you need a standard 'spell' command for this to work, which # might involve installing aspell, ispell, or pspell on your system. tempfile="/tmp/ 
 #!/bin/sh # shpell - An interactive spell-checking program that lets you step # through all known spelling errors in a document, indicate which # ones you'd like to fix and how, and apply the changes to the file # The original version of the file is saved with a .shp suffix, # and the new version replaces the old. # # Note that you need a standard 'spell' command for this to work, which # might involve installing aspell, ispell, or pspell on your system. tempfile="/tmp/$0.$$" changerequests="/tmp/$0.$$.sed" spell="ispell -l" # modify as needed for your own spell trap "rm -f $tempfile $changerequests" EXIT HUP INT QUIT TERM # Include the ansi color sequence definitions . script-library.sh initializeANSI getfix() { # Asks the user to specify a correction. If the user enters a replacement word # that's also misspelled, the function calls itself, which is a level 2 nesting. # This can go as deep as the user might need, but keeping track of nesting enables # us to ensure that only level 1 outputs the "replacing word" message. word=$1 filename=$2 misspelled=1 while [ $misspelled -eq 1 ] do echo ""; echo "${boldon}Misspelled word ${word}:${boldoff}" grep -n $word $filename  sed -e 's/^/ /' -e "s/$word/$boldon$word$boldoff/g" echo -n "i)gnore, q)uit, or type replacement: " read fix if [ "$fix" = "q" -o "$fix" = "quit" ] ; then echo "Exiting without applying any fixes."; exit 0 elif [ "${fix%${fix#?}}" = "!" ] ; then misspelled =0 # user forcing replacement, stop checking echo "s/$word/${fix#?}/g" >> $changerequests elif [ "$fix" = "i" -o -z "$fix" ] ; then misspelled=0 else if [ ! -z "$(echo $fix  sed 's/[^ ]//g')" ] ; then misspelled=0 # once we see spaces, we stop checking echo "s/$word/$fix/g" >> $changerequests else # It's a single-word replacement, let's spell-check the replacement too if [ ! -z "$(echo $fix  $spell)" ] ; then echo "" echo "*** Your suggested replacement $fix is misspelled." echo "*** Preface the word with '!' to force acceptance." else misspelled=0 # suggested replacement word is acceptable echo "s/$word/$fix/g" >> $changerequests fi fi fi done } ### Beginning of actual script body if [ $# -lt 1 ] ; then echo "Usage: $0 filename" >&2 ; exit 1 fi if [ ! -r $1 ] ; then echo "$0: Cannot read file $1 to check spelling" >&2 ; exit 1 fi # Note that the following invocation fills $tempfile along the way errors="$($spell < $1  tee $tempfile  wc -l  sed 's/[^[:digit:]]//g')" if [ $errors -eq 0 ] ; then echo "There are no spelling errors in $1."; exit 0 fi echo "We need to fix $errors misspellings in the document. Remember that the" echo "default answer to the spelling prompt is 'ignore', if you're lazy." touch $changerequests for word in $(cat $ tempfile ) do getfix $word $1 1 done if [ $(wc -l < $changerequests) -gt 0 ] ; then sed -f $changerequests $1 > $1.new mv $1 $1.shp mv $1.new $1 echo Done. Made $(wc -l < $changerequests) changes. fi exit 0 
.$$" changerequests="/tmp/
 #!/bin/sh # shpell - An interactive spell-checking program that lets you step # through all known spelling errors in a document, indicate which # ones you'd like to fix and how, and apply the changes to the file # The original version of the file is saved with a .shp suffix, # and the new version replaces the old. # # Note that you need a standard 'spell' command for this to work, which # might involve installing aspell, ispell, or pspell on your system. tempfile="/tmp/$0.$$" changerequests="/tmp/$0.$$.sed" spell="ispell -l" # modify as needed for your own spell trap "rm -f $tempfile $changerequests" EXIT HUP INT QUIT TERM # Include the ansi color sequence definitions . script-library.sh initializeANSI getfix() { # Asks the user to specify a correction. If the user enters a replacement word # that's also misspelled, the function calls itself, which is a level 2 nesting. # This can go as deep as the user might need, but keeping track of nesting enables # us to ensure that only level 1 outputs the "replacing word" message. word=$1 filename=$2 misspelled=1 while [ $misspelled -eq 1 ] do echo ""; echo "${boldon}Misspelled word ${word}:${boldoff}" grep -n $word $filename  sed -e 's/^/ /' -e "s/$word/$boldon$word$boldoff/g" echo -n "i)gnore, q)uit, or type replacement: " read fix if [ "$fix" = "q" -o "$fix" = "quit" ] ; then echo "Exiting without applying any fixes."; exit 0 elif [ "${fix%${fix#?}}" = "!" ] ; then misspelled =0 # user forcing replacement, stop checking echo "s/$word/${fix#?}/g" >> $changerequests elif [ "$fix" = "i" -o -z "$fix" ] ; then misspelled=0 else if [ ! -z "$(echo $fix  sed 's/[^ ]//g')" ] ; then misspelled=0 # once we see spaces, we stop checking echo "s/$word/$fix/g" >> $changerequests else # It's a single-word replacement, let's spell-check the replacement too if [ ! -z "$(echo $fix  $spell)" ] ; then echo "" echo "*** Your suggested replacement $fix is misspelled." echo "*** Preface the word with '!' to force acceptance." else misspelled=0 # suggested replacement word is acceptable echo "s/$word/$fix/g" >> $changerequests fi fi fi done } ### Beginning of actual script body if [ $# -lt 1 ] ; then echo "Usage: $0 filename" >&2 ; exit 1 fi if [ ! -r $1 ] ; then echo "$0: Cannot read file $1 to check spelling" >&2 ; exit 1 fi # Note that the following invocation fills $tempfile along the way errors="$($spell < $1  tee $tempfile  wc -l  sed 's/[^[:digit:]]//g')" if [ $errors -eq 0 ] ; then echo "There are no spelling errors in $1."; exit 0 fi echo "We need to fix $errors misspellings in the document. Remember that the" echo "default answer to the spelling prompt is 'ignore', if you're lazy." touch $changerequests for word in $(cat $ tempfile ) do getfix $word $1 1 done if [ $(wc -l < $changerequests) -gt 0 ] ; then sed -f $changerequests $1 > $1.new mv $1 $1.shp mv $1.new $1 echo Done. Made $(wc -l < $changerequests) changes. fi exit 0 
.$$.sed" spell="ispell -l" # modify as needed for your own spell trap "rm -f $tempfile $changerequests" EXIT HUP INT QUIT TERM # Include the ansi color sequence definitions . script-library.sh initializeANSI getfix() { # Asks the user to specify a correction. If the user enters a replacement word # that's also misspelled, the function calls itself, which is a level 2 nesting. # This can go as deep as the user might need, but keeping track of nesting enables # us to ensure that only level 1 outputs the "replacing word" message. word= filename= misspelled=1 while [ $misspelled -eq 1 ] do echo ""; echo "${boldon}Misspelled word ${word}:${boldoff}" grep -n $word $filename sed -e 's/^/ /' -e "s/$word/$boldon$word$boldoff/g" echo -n "i)gnore, q)uit, or type replacement: " read fix if [ "$fix" = "q" -o "$fix" = "quit" ] ; then echo "Exiting without applying any fixes."; exit 0 elif [ "${fix%${fix#?}}" = "!" ] ; then misspelled=0 # user forcing replacement, stop checking echo "s/$word/${fix#?}/g" >> $changerequests elif [ "$fix" = "i" -o -z "$fix" ] ; then misspelled=0 else if [ ! -z "$(echo $fix sed 's/[^ ]//g')" ] ; then misspelled=0 # once we see spaces, we stop checking echo "s/$word/$fix/g" >> $changerequests else # It's a single-word replacement, let's spell-check the replacement too if [ ! -z "$(echo $fix $spell)" ] ; then echo "" echo "*** Your suggested replacement $fix is misspelled." echo "*** Preface the word with '!' to force acceptance." else misspelled=0 # suggested replacement word is acceptable echo "s/$word/$fix/g" >> $changerequests fi fi fi done } ### Beginning of actual script body if [ $# -lt 1 ] ; then echo "Usage:
 #!/bin/sh # shpell - An interactive spell-checking program that lets you step # through all known spelling errors in a document, indicate which # ones you'd like to fix and how, and apply the changes to the file # The original version of the file is saved with a .shp suffix, # and the new version replaces the old. # # Note that you need a standard 'spell' command for this to work, which # might involve installing aspell, ispell, or pspell on your system. tempfile="/tmp/$0.$$" changerequests="/tmp/$0.$$.sed" spell="ispell -l" # modify as needed for your own spell trap "rm -f $tempfile $changerequests" EXIT HUP INT QUIT TERM # Include the ansi color sequence definitions . script-library.sh initializeANSI getfix() { # Asks the user to specify a correction. If the user enters a replacement word # that's also misspelled, the function calls itself, which is a level 2 nesting. # This can go as deep as the user might need, but keeping track of nesting enables # us to ensure that only level 1 outputs the "replacing word" message. word=$1 filename=$2 misspelled=1 while [ $misspelled -eq 1 ] do echo ""; echo "${boldon}Misspelled word ${word}:${boldoff}" grep -n $word $filename  sed -e 's/^/ /' -e "s/$word/$boldon$word$boldoff/g" echo -n "i)gnore, q)uit, or type replacement: " read fix if [ "$fix" = "q" -o "$fix" = "quit" ] ; then echo "Exiting without applying any fixes."; exit 0 elif [ "${fix%${fix#?}}" = "!" ] ; then misspelled =0 # user forcing replacement, stop checking echo "s/$word/${fix#?}/g" >> $changerequests elif [ "$fix" = "i" -o -z "$fix" ] ; then misspelled=0 else if [ ! -z "$(echo $fix  sed 's/[^ ]//g')" ] ; then misspelled=0 # once we see spaces, we stop checking echo "s/$word/$fix/g" >> $changerequests else # It's a single-word replacement, let's spell-check the replacement too if [ ! -z "$(echo $fix  $spell)" ] ; then echo "" echo "*** Your suggested replacement $fix is misspelled." echo "*** Preface the word with '!' to force acceptance." else misspelled=0 # suggested replacement word is acceptable echo "s/$word/$fix/g" >> $changerequests fi fi fi done } ### Beginning of actual script body if [ $# -lt 1 ] ; then echo "Usage: $0 filename" >&2 ; exit 1 fi if [ ! -r $1 ] ; then echo "$0: Cannot read file $1 to check spelling" >&2 ; exit 1 fi # Note that the following invocation fills $tempfile along the way errors="$($spell < $1  tee $tempfile  wc -l  sed 's/[^[:digit:]]//g')" if [ $errors -eq 0 ] ; then echo "There are no spelling errors in $1."; exit 0 fi echo "We need to fix $errors misspellings in the document. Remember that the" echo "default answer to the spelling prompt is 'ignore', if you're lazy." touch $changerequests for word in $(cat $ tempfile ) do getfix $word $1 1 done if [ $(wc -l < $changerequests) -gt 0 ] ; then sed -f $changerequests $1 > $1.new mv $1 $1.shp mv $1.new $1 echo Done. Made $(wc -l < $changerequests) changes. fi exit 0 
filename" >&2 ; exit 1 fi if [ ! -r ] ; then echo "
 #!/bin/sh # shpell - An interactive spell-checking program that lets you step # through all known spelling errors in a document, indicate which # ones you'd like to fix and how, and apply the changes to the file # The original version of the file is saved with a .shp suffix, # and the new version replaces the old. # # Note that you need a standard 'spell' command for this to work, which # might involve installing aspell, ispell, or pspell on your system. tempfile="/tmp/$0.$$" changerequests="/tmp/$0.$$.sed" spell="ispell -l" # modify as needed for your own spell trap "rm -f $tempfile $changerequests" EXIT HUP INT QUIT TERM # Include the ansi color sequence definitions . script-library.sh initializeANSI getfix() { # Asks the user to specify a correction. If the user enters a replacement word # that's also misspelled, the function calls itself, which is a level 2 nesting. # This can go as deep as the user might need, but keeping track of nesting enables # us to ensure that only level 1 outputs the "replacing word" message. word=$1 filename=$2 misspelled=1 while [ $misspelled -eq 1 ] do echo ""; echo "${boldon}Misspelled word ${word}:${boldoff}" grep -n $word $filename  sed -e 's/^/ /' -e "s/$word/$boldon$word$boldoff/g" echo -n "i)gnore, q)uit, or type replacement: " read fix if [ "$fix" = "q" -o "$fix" = "quit" ] ; then echo "Exiting without applying any fixes."; exit 0 elif [ "${fix%${fix#?}}" = "!" ] ; then misspelled =0 # user forcing replacement, stop checking echo "s/$word/${fix#?}/g" >> $changerequests elif [ "$fix" = "i" -o -z "$fix" ] ; then misspelled=0 else if [ ! -z "$(echo $fix  sed 's/[^ ]//g')" ] ; then misspelled=0 # once we see spaces, we stop checking echo "s/$word/$fix/g" >> $changerequests else # It's a single-word replacement, let's spell-check the replacement too if [ ! -z "$(echo $fix  $spell)" ] ; then echo "" echo "*** Your suggested replacement $fix is misspelled." echo "*** Preface the word with '!' to force acceptance." else misspelled=0 # suggested replacement word is acceptable echo "s/$word/$fix/g" >> $changerequests fi fi fi done } ### Beginning of actual script body if [ $# -lt 1 ] ; then echo "Usage: $0 filename" >&2 ; exit 1 fi if [ ! -r $1 ] ; then echo "$0: Cannot read file $1 to check spelling" >&2 ; exit 1 fi # Note that the following invocation fills $tempfile along the way errors="$($spell < $1  tee $tempfile  wc -l  sed 's/[^[:digit:]]//g')" if [ $errors -eq 0 ] ; then echo "There are no spelling errors in $1."; exit 0 fi echo "We need to fix $errors misspellings in the document. Remember that the" echo "default answer to the spelling prompt is 'ignore', if you're lazy." touch $changerequests for word in $(cat $ tempfile ) do getfix $word $1 1 done if [ $(wc -l < $changerequests) -gt 0 ] ; then sed -f $changerequests $1 > $1.new mv $1 $1.shp mv $1.new $1 echo Done. Made $(wc -l < $changerequests) changes. fi exit 0 
: Cannot read file to check spelling" >&2 ; exit 1 fi # Note that the following invocation fills $tempfile along the way errors="$($spell < tee $tempfile wc -l sed 's/[^[:digit:]]//g')" if [ $errors -eq 0 ] ; then echo "There are no spelling errors in ."; exit 0 fi echo "We need to fix $errors misspellings in the document. Remember that the" echo "default answer to the spelling prompt is 'ignore', if you're lazy." touch $changerequests for word in $(cat $tempfile) do getfix $word 1 done if [ $(wc -l < $changerequests) -gt 0 ] ; then sed -f $changerequests > .new mv .shp mv .new echo Done. Made $(wc -l < $changerequests) changes. fi exit 0

How It Works

The script itself revolves around the getfix function, which shows each error in its context and then prompts the user for either a correction or permission to ignore each error. The sophisticated conditionals in this script allow users to type in either a correction for the reported misspelling, i to ignore the misspelling, or q to immediately quit the program. Perhaps more interesting is that getfix is interactive. It checks the spelling of the corrections that are entered to ensure that you're not trading one misspelling for another. If the script thinks that the correction is a misspelling too, you can force acceptance of the correction by prefacing it with the "!" character.

The fixes themselves are accumulated by a sed script called $changerequests , which is then used to apply the corrections to the file once the user has finished reviewing all of the would-be mistakes.

Also worth mentioning is that the trap command at the beginning of the script ensures that any temp files are removed. Finally, if you check the last few lines of the script, you'll note that the precorrected version of the file is saved with a .shp suffix, in case something goes wrong. Anticipating possible problems is always a wise policy, particularly for scripts that munge input files.

Running the Script

To run this script, specify the filename to spell-check as a command argument.

The Results

 $  shpell ragged.txt  We need to fix 5 misspellings in the document. Remember that the default answer to the spelling prompt is 'ignore', if you're lazy. Misspelled word herrself:    1:So she sat on, with closed eyes, and half believed herrself in i)gnore, q)uit, or type replacement:  herself  Misspelled word reippling:    3:all would change to dull reality--the grass would be only rustling in the wind, and the pool reippling to the waving of the reeds--the i)gnore, q)uit, or type replacement:  rippling  Misspelled word teacups:    4:rattling teacups would change to tinkling sheep-bells, and the i)gnore, q)uit, or type replacement: Misspelled word Gryphon:    7:of the baby, the shriek of the Gryphon, and all the other queer noises, would change (she knew) i)gnore, q)uit, or type replacement: Misspelled word clamour:    8:to the confused clamour of the busy farm-yard--while the lowing of i)gnore, q)uit, or type replacement: Done. Made 2 changes. 

It's impossible to reproduce here in the book, but the ANSI color sequences let the misspelled words stand out in the output display.




Wicked Cool Shell Scripts. 101 Scripts for Linux, Mac OS X, and Unix Systems
Wicked Cool Shell Scripts
ISBN: 1593270127
EAN: 2147483647
Year: 2004
Pages: 150
Authors: Dave Taylor

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net