I am using agrep
to find similar spelling words, for example:
agrep -1 hack /usr/share/dict/words
But it returns too many words, so I also hope the length of the word is same as the keyword. How can I specify that?
The key to using agrep
is to recognize that you can control the cost for things like adding, substituting, and deleting characters. For insertion it's the -I
switch. For deletion it's -D
.
$ agrep -1 -I2 -D2 '^hack$' /usr/share/dict/words
$ agrep -1 -I2 -D2 '^hack$' /usr/share/dict/words
back
cack
fack
haak
hack
haik
hank
hark
hask
hawk
heck
hick
hock
huck
Jack
jack
lack
Mack
mack
Pack
pack
rack
sack
tack
Wack
wack
yack
Zack
zack
So if we set the cost of insertion 1 higher than the number of errors we're willing to tolerate, and do the same for the cost of deletions, we'll never insert or delete any characters, thus maintaining our length, which is the length of the pattern we're matching, hack
, i.e. 4.
So in the above command we've set our margin of error at 1 (-1
). We've set our cost of doing and insertion or a deletion to 2 (-I2 -D2
). And we've guarded our results so that they only match strings that are whole words which begin and end with our pattern, (^hack$
).
NOTE: The caret (^
) means the beginning of the string, and the dollar sign ($
) the end. These are called anchors.
As an alternative you can also use 2 agreps.
$ agrep '^[a-zA-Z]{4}$' /usr/share/dict/words | agrep -1 'hack'
$ agrep '^[a-zA-Z]{4}$' /usr/share/dict/words | agrep -1 'hack'
back
cack
Chac
Chak
dhak
fack
haak
hack
haik
hake
hako
haku
hank
hark
hask
hawk
heck
hick
hock
huck
Jack
jack
lack
Mack
mack
Pack
pack
rack
sack
Shak
tack
thak
Wack
wack
yack
Zack
zack
The first agrep
is tasked with finding the set of strings that are 4 characters in length. The second agrep
reduces this set further to only strings matching your pattern of hack
with a single error allowed.
I don't know how you could specify that to agrep
However, you might be able to use the shell to solve your problem. For example, with bash
. In the following:
Set the variable keyword
to hack
Set the length of keyword
into
l
Pass l
into awk
via a variable named limit
, and specify
that awk
print records whose length (as determined by the awk
built-in function length
) is equal to limit
keyword=hack; l=${#keyword};
agrep -1 $keyword /usr/share/dict/words | awk -v limit=$l 'length == limit'
Jack
Mack
back
hack
hake
hank
hark
hawk
heck
hick
hock
jack
lack
pack
rack
sack
tack
yack