Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

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?

share|improve this question
add comment

2 Answers

up vote 5 down vote accepted

Using 1 agrep

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

Example

$ 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

Details

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.

Using 2 agreps

As an alternative you can also use 2 agreps.

$ agrep '^[a-zA-Z]{4}$' /usr/share/dict/words | agrep -1 'hack'

Example

$ 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

Details

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.

share|improve this answer
    
Thanks. What does "^hack$" mean? –  Tim Dec 21 '13 at 2:33
    
It anchors the string making sure that it's the beginning and the end of the line. –  slm Dec 21 '13 at 2:36
    
but "ack" doesn't begin or end with "hack"? –  Tim Dec 21 '13 at 2:38
    
@Tim - yeah I'm just noticing that, investigating. –  slm Dec 21 '13 at 2:38
    
@Tim - see updates, figured it out! –  slm Dec 21 '13 at 3:21
add comment

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
share|improve this answer
    
Thanks! can you explain "awk -v limit=$l 'length() == limit'"? Is length() a function? How does it know what its argument is? –  Tim Dec 21 '13 at 2:24
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.