我在命令中使用两个文件,第一个文件 ( 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
只会计算 uniq 实例,所以它会给你每个单词的计数,而不是传递给它的所有单词的计数,然后你只获取第一个输出。
答案2
从扎卡里·布雷迪版本开始:
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
(example^[^a]*a[^a]*a[^a]*$
)- grep -c ... 统计匹配单词的数量
- grep -m 1 ... 获取第一个匹配的单词
- Paste - - - ... 将 3 条输出行合并为一行
如果您喜欢随机单词示例,请将第二个 grep 替换为
grep "^[^$i]*$i[^$i]*$i[^$i]*$" file1 | shuf | head -1
“确保恰好两个”的另一种选择是找到 2 个 aa 并拒绝如果 aaa:
grep 'a.*a' file1 | grep -vc 'a.*a.*a'
答案3
这里有两种方法可以做到这一点,一种是面向 shell 的(主要使用 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 是不必要的,但我无缘无故地添加了它们以更接近“使用 grep 排序和 uniq”要求。
awk的解决方案:
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