使用Linux命令行解决Wordle
使用 Linux grep 和 fgrep 命令赢得您最喜欢的单词猜谜游戏。
我最近有点迷上了一个在线单词益智游戏,在这个游戏中,你有六次尝试来猜测一个随机的五个字母的单词。这个词每天都在变化,而且每天只能玩一次。每次猜测后,您猜测的每个字母都会突出显示:灰色表示该字母未出现在神秘单词中,黄色表示该字母出现在单词中但不在该位置,绿色表示该字母出现在单词中那个正确的位置。
下面介绍了如何使用 Linux 命令行来帮助您玩 Wordle 等猜谜游戏。我用这个方法帮助我解决了 1 月 6 日的难题:
第一次尝试
Linux 系统在 /usr/share/dict/words
文件中保存单词字典。这是一个很长的纯文本文件。我的系统的单词文件有超过 479,800 个条目。该文件包含普通单词和专有名词(名称、地点等)。
为了开始我的第一个猜测,我只想要一个恰好五个字母长的简单单词列表。为此,我使用这个 grep
命令:
$ grep '^[a-z][a-z][a-z][a-z][a-z]$' /usr/share/dict/words > myguess
grep
命令使用正则表达式来执行搜索。您可以使用正则表达式做很多事情,但为了帮助我解决 Wordle,我只需要基础知识: ^
表示行的开头,$
表示一行的末尾。在这之间,我指定了 [a-z]
的五个实例,表示从 a 到 z 的任何小写字母。
我还可以使用 wc
命令来查看我的可能单词列表“仅”15,000 个单词:
$ wc -l myguess
15034 myguess
从该列表中,我随机选择了一个由五个字母组成的单词:英亩。 a 设置为黄色,这意味着该字母存在于神秘单词中的某个位置,但不在第一个位置。其他字母是灰色的,所以我知道它们不存在于当天的单词中。
吉姆·霍尔(CC BY-SA 4.0)
第二次尝试
对于我的下一个猜测,我想要获取包含 a 但不在第一个位置的所有单词的列表。我的列表也不应包含字母 c、 r、e 或 s。让我们将其分解为几个步骤:
要获取所有带有 a 的单词的列表,我使用 fgrep(固定字符串 grep)命令。 fgrep
命令还可以搜索 grep
等文本,但不使用正则表达式:
$ fgrep a myguess > myguess2
这使我可能的下一个猜测列表从 15,000 个单词减少到 6,600 个单词:
$ wc -l myguess myguess2
15034 myguess
6634 myguess2
21668 total
但该单词列表的第一个位置还包含字母 a,这是我不想要的。游戏已经表明字母a存在于其他位置。我可以使用 grep 修改命令来查找第一个位置包含其他字母的单词。这将我可能的猜测缩小到只有 5,500 个单词:
$ fgrep a myguess | grep '^[b-z]' > myguess2
$ wc -l myguess myguess2
15034 myguess
5566 myguess2
20600 total
但我知道这个神秘词也不包含字母 c、r、e 或 s。我可以使用另一个 grep 命令从搜索中省略这些字母:
$ fgrep a myguess | grep '^[b-z]' | grep -v '[cres]' > myguess2
$ wc -l myguess myguess2
15034 myguess
1257 myguess2
16291 total
-v
选项表示反转搜索,因此 grep
只会返回与正则表达式 [cres]
或不匹配的行字母 c、r、e 或 s 的单个列表。有了这个额外的 grep
命令,我已经将下一个猜测范围大大缩小到只有 1,200 个可能的单词,其中某处有 a 但不在第一个位置,并且不包含 c 、r、e 或 s。
查看列表后,我决定尝试一下“balmy”这个词。
吉姆·霍尔(CC BY-SA 4.0)
第三次尝试
这次,字母 b 和 a 以绿色突出显示,这意味着我将这些字母放在正确的位置。字母 l是黄色的,因此该字母存在于单词中的其他位置,但不在该位置。字母 m 和 y 是灰色的,因此我可以从下一次猜测中消除它们。
为了确定下一个可能的单词列表,我可以使用另一组 grep
命令。我知道这个词以 ba 开头,所以我可以从那里开始搜索:
$ grep '^ba' myguess2 > myguess3
$ wc -l myguess3
77 myguess3
这只有77个字!我可以通过查找在除第三个位置之外的任何位置也包含字母 l 的单词来进一步缩小范围:
$ grep '^ba[^l]' myguess2 > myguess3
$ wc -l myguess3
61 myguess3
方括号 [^l]
内的^
表示不是此字母列表,因此不是字母l。这使得我的可能单词列表达到 61 个,并非所有单词都包含字母 l,我可以使用另一个 grep
搜索来消除它:
$ grep '^ba[^l]' myguess2 | fgrep l > myguess3
$ wc -l myguess3
10 myguess3
其中一些单词可能包含字母 m 和 y,这些字母不在今天的神秘单词中。我可以通过另一个反向 grep
搜索从我的猜测列表中删除这些内容:
$ grep '^ba[^l]' myguess2 | fgrep l | grep -v '[my]' > myguess3
$ wc -l myguess3
7 myguess3
我的可能单词列表现在很短,只有七个单词!
$ cat myguess3
babul
bailo
bakal
bakli
banal
bauld
baulk
我会选择平庸作为我下一个猜测的可能词,而这个猜测恰好是正确的。
吉姆·霍尔(CC BY-SA 4.0)
正则表达式的威力
Linux 命令行提供了强大的工具来帮助您完成实际工作。 grep
和 fgrep
命令在扫描单词列表方面提供了极大的灵活性。对于基于单词的猜谜游戏,grep
帮助识别了当天 15,000 个可能单词的列表。在猜测并了解神秘单词中出现和未出现的字母后,grep
和 fgrep
帮助将选项范围缩小到 1,200 个单词,然后只剩下 7 个单词。这就是命令行的力量。