Grep 单词正好有两个元音
Grep words with exact two vowels
我遇到以下问题,我需要从文件中检索恰好包含 2 个元音(以任何顺序)的所有单词。该文件每行仅包含一个单词。
我目前的解决方法是:
Grep1: 检索词如earth, over, under, one...
grep -i "^[aeiou][^aeiou]*[aeiou][^aeiou]*$" genesis.words > A.txt
和
Grep2: 检索词如formless, deep, said...
grep -i "^[^aeiou][^aeiou]*[aeiou][^aeiou]*[aeiou][^aeiou]*$" genesis.words > B.txt
上述解决方案有效,但是当我将两个正则表达式连接成一个正则表达式时,return 什么都没有!
Grep1 和 Grep2 之母: 应该检索所有内容!
grep -i "^[aeiou][^aeiou]*[aeiou][^aeiou]*$|^[^aeiou][^aeiou]*[aeiou][^aeiou]*[aeiou][^aeiou]*$" genesis.words
我认为问题出在我在表达式中实现 ^$
但尝试了差异版本但没有成功!
非常感谢任何帮助!
OS 是 AIX 6100-09-04-1441
由于 *
可以匹配 0 次或更多次,因此您应该能够以 [^aeiou]*
开始字符串:try
"^[^aeiou]*[aeiou][^aeiou]*[aeiou][^aeiou]*$"
至于修复你的正则表达式,我认为你需要将栏转义为 \|
,所以
grep -i "^[aeiou][^aeiou]*[aeiou][^aeiou]*$\|^[^aeiou][^aeiou]*[aeiou][^aeiou]*[aeiou][^aeiou]*$" genesis.words
如果你不介意Perl
,你可以使用这个:
perl -lne '$m=$_; tr/[aeiou]//cd; print $m if length()==2;' /usr/share/dict/words
也就是说... "save the current line (word) in $m. Delete everything that is not a vowel. Print the original word if there are two things (i.e vowels) left."
请注意,我使用系统词典作为测试的输入。
您可以在 awk
中做几乎相同的事情。
你很接近。这应该有效:
grep -i "^[^aeiou]*[aeiou][^aeiou]*[aeiou][^aeiou]*$" genesis.words > A.txt
所以它应该找到所有八种可能性(两个元音识别三个非元音序列,每个都可能为空;2^3 是 8):
[ ]I[ ]o[ ]
[ ]e[ ]a[r]
[ ]e[r]a[ ]
[ ]e[l]a[n]
[T]e[ ]a[ ]
[D]e[ ]a[r]
[D]e[w]a[r]
[D]a[w]a[ ]
[H]a[w]a[y]
至于串联,|需要逃避。您可以使用单个锚点:
^(regexp1\|regexp2)$
如果您能够使用带有 wc
的 grep tr
的替代方法效果很好:
words=/path/to/words.txt
while read -e word ; do
v=$(echo $word | tr -cd 'aeiou' | wc -c)
[[ ! $v -eq "2" ]] || echo $word >> output.txt
done < $words
这逐行读取原始文件,计算元音和 returns 结果只有 2 到 output.txt。
我遇到以下问题,我需要从文件中检索恰好包含 2 个元音(以任何顺序)的所有单词。该文件每行仅包含一个单词。
我目前的解决方法是:
Grep1: 检索词如earth, over, under, one...
grep -i "^[aeiou][^aeiou]*[aeiou][^aeiou]*$" genesis.words > A.txt
和
Grep2: 检索词如formless, deep, said...
grep -i "^[^aeiou][^aeiou]*[aeiou][^aeiou]*[aeiou][^aeiou]*$" genesis.words > B.txt
上述解决方案有效,但是当我将两个正则表达式连接成一个正则表达式时,return 什么都没有!
Grep1 和 Grep2 之母: 应该检索所有内容!
grep -i "^[aeiou][^aeiou]*[aeiou][^aeiou]*$|^[^aeiou][^aeiou]*[aeiou][^aeiou]*[aeiou][^aeiou]*$" genesis.words
我认为问题出在我在表达式中实现 ^$
但尝试了差异版本但没有成功!
非常感谢任何帮助!
OS 是 AIX 6100-09-04-1441
由于 *
可以匹配 0 次或更多次,因此您应该能够以 [^aeiou]*
开始字符串:try
"^[^aeiou]*[aeiou][^aeiou]*[aeiou][^aeiou]*$"
至于修复你的正则表达式,我认为你需要将栏转义为 \|
,所以
grep -i "^[aeiou][^aeiou]*[aeiou][^aeiou]*$\|^[^aeiou][^aeiou]*[aeiou][^aeiou]*[aeiou][^aeiou]*$" genesis.words
如果你不介意Perl
,你可以使用这个:
perl -lne '$m=$_; tr/[aeiou]//cd; print $m if length()==2;' /usr/share/dict/words
也就是说... "save the current line (word) in $m. Delete everything that is not a vowel. Print the original word if there are two things (i.e vowels) left."
请注意,我使用系统词典作为测试的输入。
您可以在 awk
中做几乎相同的事情。
你很接近。这应该有效:
grep -i "^[^aeiou]*[aeiou][^aeiou]*[aeiou][^aeiou]*$" genesis.words > A.txt
所以它应该找到所有八种可能性(两个元音识别三个非元音序列,每个都可能为空;2^3 是 8):
[ ]I[ ]o[ ]
[ ]e[ ]a[r]
[ ]e[r]a[ ]
[ ]e[l]a[n]
[T]e[ ]a[ ]
[D]e[ ]a[r]
[D]e[w]a[r]
[D]a[w]a[ ]
[H]a[w]a[y]
至于串联,|需要逃避。您可以使用单个锚点:
^(regexp1\|regexp2)$
如果您能够使用带有 wc
的 grep tr
的替代方法效果很好:
words=/path/to/words.txt
while read -e word ; do
v=$(echo $word | tr -cd 'aeiou' | wc -c)
[[ ! $v -eq "2" ]] || echo $word >> output.txt
done < $words
这逐行读取原始文件,计算元音和 returns 结果只有 2 到 output.txt。