내 명령에서 두 개의 파일을 사용하고 있는데 첫 번째 파일( file1
)은 알파벳의 각 문자가 별도의 줄에 있는 파일입니다. 두 번째 파일( $w
내 명령에서)은 거대한 단어 목록입니다. 알파벳 목록과 단어 목록을 비교하여 알파벳 문자를 두 번 포함하는 단어를 찾고, 각 문자에 대한 단어 수와 예제 단어를 표시해야 합니다. 출력은 다음과 같지만 전체 알파벳에 대해
v 94 bivalve
w 94 awkward
x 3 executrix
y 196 abysmally
z 58 bedazzle
아래는 내 명령과 그 결과입니다
for i in `cat file1`; do grep $i.*$i $w | sort | uniq -c | head -1; done
1 aardvark
1 abba
1 acacia
1 abandoned
1 abalienate
1 affability
1 ageing
1 aforethought
1 abalienation
1 hajj
1 backstroke
1 abnormally
1 accommodate
1 abalienation
1 abdominous
1 agitprop
1 quinqevalent
1 aardvark
1 abbess
1 abatement
1 absquatulate
1 bivalve
1 awkward
1 executrix
1 abysmally
1 bedazzle
답변1
비교적 새로운 버전을 사용한다고 가정하면 bash
비슷한 작업을 수행할 수 있습니다.
for CHAR in {a..z}
do
WORD_LIST=( $(grep "$CHAR.*$CHAR" $w) )
echo $CHAR ${#WORD_LIST[@]} ${WORD_LIST[0]}
done
우리는 크기 개수를 제공하는 bash 배열을 사용하고 ${#WORD_LIST[@]}
있으며 배열의 첫 번째 요소를 가져오고 있습니다 ${WORD_LIST[0]}
.
귀하의 예가 작동하지 않는 이유는 uniq -c
고유한 인스턴스만 계산하므로 전달된 모든 단어의 수가 아닌 각 단어의 수를 제공하고 첫 번째 출력만 얻을 수 있기 때문입니다.
답변2
Zachary Brady 버전부터 시작:
for i in {a..z}
do
( echo $i ;
grep -c "^[^$i]*$i[^$i]*$i[^$i]*$" file1;
grep -m 1 "^[^$i]*$i[^$i]*$i[^$i]*$" file1
) | paste - - -
done
"^[^$i]*$i[^$i]*$i[^$i]*$"
정확히 2번 발생하는지 확인하는 것입니다$i
(예^[^a]*a[^a]*a[^a]*$
).- grep -c ... 일치하는 단어 수를 계산합니다.
- grep -m 1 ... 첫 번째로 일치하는 단어를 얻습니다.
- 붙여넣기 - - - ... 3개의 출력 라인을 하나로 병합
임의의 단어 예를 선호하는 경우 두 번째 grep을 다음으로 바꾸십시오.
grep "^[^$i]*$i[^$i]*$i[^$i]*$" file1 | shuf | head -1
"정확히 2개가 있는지 확인"하는 또 다른 옵션은 2 aa를 찾아 aaa인 경우 거부하는 것입니다.
grep 'a.*a' file1 | grep -vc 'a.*a.*a'
답변3
이를 수행하는 방법에는 두 가지가 있습니다. 하나는 쉘 지향(주로 grep 사용)이고 다른 하나는 awk를 사용하는 것입니다.
w=/usr/share/dict/words
sort file1 | uniq | while read letter
do
count=$(grep -ic "^[^$letter]*$letter[^$letter]*$letter[^$letter]*$" "$w")
r=$(( (RANDOM % count) + 1 ))
printf "%s %d %s\n" "$letter" $count \
$(grep -i "^[^$letter]*$letter[^$letter]*$letter[^$letter]*$" "$w" | \
sed -n ${r}p )
done
file1이 지시된 대로(한 줄에 한 글자씩) 준비된 경우 초기 정렬 및 uniq는 필요하지 않지만 "정렬 및 uniq에 grep 사용" 요구 사항에 더 가까워지기 위해 아무 이유 없이 추가했습니다.
이상한 해결책 :
BEGIN {
split("abcdefghijklmnopqrstuvwxyz", alphabet, "");
srand();
}
{
for (i in alphabet) {
letter=alphabet[i]
if (match(tolower($1), "^[^"letter"]*"letter"[^"letter"]*"letter"[^"letter"]*$")) {
counts[letter]++
if (wordfor[letter]) {
if (rand() * counts[letter] >= counts[letter] - 1)
wordfor[letter]=$1
} else
wordfor[letter]=$1
}
}
}
END {
for (i in alphabet)
print alphabet[i], counts[alphabet[i]], wordfor[alphabet[i]]
}
파일에 저장하고 다음과 같이 사용하십시오.
w=/usr/share/dict/words ## or whatever
awk -f theabove.awk "$w" | sort