Click here to show toolbars of the Web Online Help System: show toolbars |
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.
#!/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
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.
$ 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.
This HTML Help has been published using the chm2web software. |