私のコマンドは2つのファイルを使用していますが、最初のファイル(file1
)はアルファベットの各文字が別々の行にあるファイルです。 2番目のファイル($w
私のコマンドでは)は巨大な単語のリストです。アルファベットリストと単語リストを比較して、アルファベット文字を2回含む単語を見つけ、各文字の単語数とサンプル単語を表示する必要があります。出力は次のとおりですが、アルファベット全体について
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本の出力ラインを1つにマージ
ランダムな単語の例を好む場合は、2番目のgrepを次に置き換えます。
grep "^[^$i]*$i[^$i]*$i[^$i]*$" file1 | shuf | head -1
「正確に2つあることを確認する」もう1つのオプションは、2 aaを見つけてaaaの場合は拒否することです。
grep 'a.*a' file1 | grep -vc 'a.*a.*a'
答え3
これを行う方法は2つあります。 1つはシェル指向(主にgrepを使用)、もう1つは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が指示どおりに(1行に1文字ずつ)準備されている場合、初期ソートと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