나는 bash에서 문자 목록이 주어지면 /usr/share/dict/words
파일의 모든 단어를 찾는 스크래블 도우미를 만들려고 합니다.
예를 들어, 문자가 주어지면 a,c,r,t
단어는 단어 와 cart
일치합니다 . 단어 도 일치합니다.car
carat
아니요성냥
그러나 만약 then이 a,a,c,r,t
주어지면 일치할 것입니다.carat
을 사용할 수 있는지 알아보고 있습니다 grep
. 이와 같은 중괄호 확장이
{a,c,r,t}{a,c,r,t}
가능한 모든 문자 조합을 생성하는 데 도움이 될 것으로 의심되지만 비슷한 오류가 발생합니다.
grep: aaac: No such file or directory
grep: aaar: No such file or directory
grep: aaat: No such file or directory
명령을 실행할 때
$ grep {a,c,r,t}{a,c,r,t}{a,c,r,t}{a,c,r,t} /usr/share/dict/words
"{a,c,r,t}{a,c,r,t}"
다음과 같은 따옴표를 사용하거나 "\{a,c,r,t\}\{a,c,r,t\}"
중괄호 확장이 전혀 작동하지 않습니다.
위 명령이 Scrabble Assistant로 작동하지 않는다는 것을 알고 있지만 오류는 여전히 예상치 못한 것입니다. 이 명령에 어떤 문제가 있으며 어떻게 해결합니까? 또한 grep
Scrabble 도우미를 만들 수 있는 방법이 있나요?
답변1
정규 표현식은 이러한 종류의 작업에 가장 적합한 도구는 아닙니다. 나는 다음과 같은 일을 할 것입니다 :
perl -CLASD -lne '
BEGIN{$l0{$_}++ for (split "", shift)}
%l = %l0; for (split "") {next LINE unless $l{$_}--}
print' aacrt < /usr/share/dict/words
아니면 그 이후로 (적어도 프랑스어와 영어로는및 라틴 알파벳을 사용하는 다른 언어), Scrabble에는 A부터 Z까지 26개의 대문자만 있고(été는 ETE로 작성되고 cœur는 COEUR로 작성됨) GNU는 다음과 같습니다 iconv
.
iconv -t us//TRANSLIT < /usr/share/dict/words |
perl -CLASD -lne '
BEGIN{$l0{$_}++ for (split "", uc shift)}
%l = %l0; for (split "", uc $_) {next LINE unless $l{$_}--}
print' croeu
또는 원시 형식으로 출력합니다.
perl -CLASD -MText::Unidecode -lne '
BEGIN{$l0{$_}++ for (split "", uc shift)}
%l = %l0; for (split "", uc unidecode $_) {next LINE unless $l{$_}--}
print' croeu < /usr/share/dict/word
답변2
여기서 일어나는 일은 {a,c,r,t}{a,c,r,t}{a,c,r,t}{a,c,r,t}
사용 중인 쉘에 의해 확장됩니다. 즉, 첫 번째 ( )는 aaaa
다음과 같이 입력한 것처럼 검색할 패턴 등임을 의미합니다.grep
aaac
aaar
grep aaaa aaac aaar aaat aaca ..... /usr/share/dict/words
이를 방지하려면 검색 패턴을 작은따옴표로 묶으세요.
grep '{a,c,r,t}{a,c,r,t}{a,c,r,t}{a,c,r,t}' /usr/share/dict/words
반면에 여기서 올바른 grep 구문을 사용하고 있는지 잘 모르겠습니다. 나는 다음을 사용할 것이다:
grep '[acrt][acrt][acrt][actr]' /usr/share/dict/words
@mueh가 언급한 것처럼 4개의 문자 조합과 일치합니다.
grep -xE '[acrt]{1,4}' /usr/share/dict/words
이 문자를 1~4개 조합으로 연결하세요.
답변3
세트에 동일한 문자가 중복되고 일부 누락된 문자가 있는 항목이 포함되어 있으므로 중괄호의 Bash 확장은 유효한 순열을 생성하지 않습니다.
필요한 것은 문자 전체 또는 일부를 사용하는 크로스워드 퍼즐 도구입니다. 다행히도 이러한 도구는 이미 표준 Linux의 일부로 존재합니다. 그것은 알려져있다하나. 그것은 사용한다/usr/share/사전/단어기본 사전으로 사용됩니다.
사용 방법에 대한 예는 다음과 같습니다.
먼저 이 함수를 정의합니다(대화형).
$ mywords() { an -w "$1" -m 4 | awk '/^[a-z]*$/ {print length($0), $0}' | column; }
이제 ypltar라는 글자가 있다고 상상해 보세요. 전체 또는 부분적으로 사용된 유효한 사전 단어를 찾으려면:
$ mywords ypltar
6 partly 5 party 4 tray 4 tarp 4 pray 4 part
6 paltry 5 aptly 4 trap 4 rapt 4 play 4 arty
출력 단어를 4자 이상으로 제한하기 위해 함수에서 -m 4를 사용했습니다. 필요에 따라 변경할 수 있습니다. awk 비트는 대문자(고유 명사 등)가 포함된 사전 항목을 제외하는 데 사용됩니다.
답변4
그래서 이것에 대한 나의 플레이는 나에게 3, ..., n개의 문자 단어를 제공하는 이 스크립트를 생성하도록 이끌었습니다. 문제는 문자가 여러 번 나타날 수 있다는 것입니다. "WordGuess stop"은 oops and toot뿐만 아니라 pots 및 post도 반환합니다. 아직도 청소 중이에요.
#!/usr/bin/bash
# WordGuess - an attempt at automated word generation for
# anagrams and word finds
# 2024-02-02 SRJ
#
WordList="/usr/share/dict/american-english"
Argument="${@}"
Length=${#Argument}
# Double this to start properly with 3 character strings below
String="[${Argument}][${Argument}]"
for ((i = 2; i < ${Length}; i++)) ; do
String="${String}[${Argument}]"
echo -n $(grep -E "^${String}$" ${WordList})" "
echo
done
실행 시간;
WordGuess stop
ops opt pop pot sop sos sot too top tot tsp oops opts
poop pops poss post pots psst soot sops sots spot stop toot tops toss tost tots
내 생각에 올바른 방법은 각 순열을 생성하고 단어 목록에서 grep을 시도하는 것이지만 이 방법은 느릴 것입니다.