如何使用grep从字典文件中查找具有给定字母集的单词出现,并限制每个字母出现一次且仅出现一次。
EG如果字母是abc,则预期输出为:
驾驶室
编辑:
给定一个字典文件(即每行包含一个单词的文件,例如mac os x操作系统上的/usr/share/dict/words
)和一组(唯一)字符,我想打印出所有字典文件的包含输入集的每个字符一次且仅包含一次的单词。例如,如果字符集为{a,b,c}
,则打印出包含该集合中每个字符的所有(3个字母)单词。
我正在寻找一个只使用grep表达式的解决方案。
答案 0 :(得分:1)
给定一系列字母,例如abc
,您可以将每个字母转换为前瞻,如下所示:
^(?=[^a]*a[^a]*)(?=[^b]*b[^b]*)(?=[^c]*c[^c]*)$
您可能需要使用"扩展的正则表达式"标记-E
以将此正则表达式与grep
一起使用。
要从字符串创建此正则表达式,您可以使用sed
(读者练习)
答案 1 :(得分:1)
grep -E ^[abc]{3}.$ <Dictionary file> | grep -v -e a.*a -e b.*b -e c.*c
即。找到与输入匹配的所有三个字母字符串,并通过反向grep管道这些字符串以删除带双字母的字符串。
我正在使用'。'在{3}之后,因为我的字典文件是基于Windows的,所以有一个额外的回车或换行。所以,这可能没有必要。
答案 2 :(得分:0)
以下是Perl解决方案。请注意,您需要向字典中添加更多单词,并将输入读入$input
变量。有效单词数组将以@results
结尾。
#!/usr/bin/env perl
use Data::Dumper;
my $input = "abc";
my @dictionary = qw(aaa aac aad aal aam aap aar aas aat aaw aba abc abd abf abg
abh abm abn abo abr abs abv abw aca acc ace aci ack acl acp acs act acv ada adb
adc add adf adh adl adn ado adp adq adr ads adt adw aea aeb aec aed aef aes aev
afb afc afe aff afg afi afk afl afn afp aft afu afv agb agc agl agm agn ago agp
...
PUT A REAL DICTIONARY HERE!
...
zie zif zig zii zij zik zil zim zin zio zip zir zis zit ziu ziv zlm zlo zlx zma
zme zmi zmu zna zoa zob zoe zog zoi zol zom zon zoo zor zos zot zou zov zoy zrn
zsr zub zud zug zui zuk zul zum zun zuo zur zus zut zuz zva zwo zye zzz);
# Generate a lookahead expression for each character in the input word
my $regexp = join("", map { "(?=.*$_)" } split(//, $input));
my @results;
foreach my $word (@dictionary) {
# If the size of the input doesn't match the dictionary word, skip to the
# next word.
if (length($input) != length($word)) {
next;
}
if ($word =~ /$regexp/) {
push(@results, $word);
}
}
print Dumper @results;
答案 3 :(得分:0)
我找到的解决方案首先使用grep
提取所有仅包含输入集中字母的n个字母单词 - 尽管有些字母可能会出现多次,有些可能不出现; (我再次假设输入字母是唯一的)。然后它会执行一系列1个字母greps
以确保每个字母至少出现一次。因为单词长度为n,所以这确保单词包含每个字母一次且仅包含一次。例如,如果输入字符集为(a,b,c}
,则解决方案为:
grep -E '^[abc]{3}$' /usr/share/dict/words | grep a | grep b | grep c
可以编写一个简单的bash脚本来创建这个grep
字符串并使用$ 1作为输入字母集对word文件执行它。它可能不是生成字符串的最有效方法,但由于我不熟悉sed
或awk
,它似乎解决了我的问题。我创建的脚本是:
#!/bin/sh
slen=${#1}
g2="'^[$1]{$slen}\$'"
g3=""
ix1=0
while [ $ix1 -lt $slen ]
do
g3="$g3 | grep ${1:$ix1:1}"
ix1=$((ix1+1))
done
eval grep -E $g2 /usr/share/dict/words $g3