【问题标题】:Grep words with exact two vowels有两个元音的 Grep 单词
【发布时间】:2016-10-08 15:13:45
【问题描述】:

我有以下问题,我需要从文件中检索包含恰好 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

上述解决方案有效,但是当我将两个正则表达式连接成一个正则表达式时,什么也不返回!

Grep1 和 Grep2 之母:应该找回所有东西!

 grep -i "^[aeiou][^aeiou]*[aeiou][^aeiou]*$|^[^aeiou][^aeiou]*[aeiou][^aeiou]*[aeiou][^aeiou]*$" genesis.words

我认为问题在于我在表达式中实现 ^$,但尝试了不同版本但没有成功!

任何帮助将不胜感激!

操作系统是 AIX 6100-09-04-1441

【问题讨论】:

    标签: grep aix


    【解决方案1】:

    如果您能够使用 grep trwc 的替代方法效果很好:

    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
    

    这会逐行读取原始文件,计算元音并将只有 2 个的结果返回到 output.txt。

    【讨论】:

    • 感谢 diff 方法 - 但是没有想到这种方式,因为这通常是从命令行(快速和肮脏)运行 grep 在这种特定情况下是最好的选择。
    【解决方案2】:

    你很亲密。这应该有效:

    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)$
    

    【讨论】:

    • 谢谢!您的解决方案就像一个魅力!至于串联,我应用了您的建议,但仍然没有返回任何内容。
    【解决方案3】:

    如果你不介意Perl,你可以使用这个:

    perl -lne '$m=$_; tr/[aeiou]//cd; print $m if length()==2;' /usr/share/dict/words
    

    也就是说... “将当前行(单词)保存在 $m 中。删除所有不是元音的内容。如果还剩下两个东西(即元音),则打印原始单词。”

    请注意,我使用系统字典作为测试的输入。

    您可以在awk 中做几乎相同的事情。

    【讨论】:

    • 这说明了为什么Perl 有时会是一门很棒的语言! +1 您提到了awk,尽管使用其中一个有什么优势吗?
    • 我想,至少对我而言,Perl 的优势在于它在 Linux、Unix、OSX、Windows 中完全相同——只有一种标准的正则表达式语法,一种一致的文件命名约定,一种标准化的行尾集,一组转义,只有一个日期语法,只有一个 find 语法,它可以做到tr 可以做的所有事情,sedawk 可以做的所有事情,grep,@ 987654331@, CPAN...
    【解决方案4】:

    由于 * 可以匹配 0 次或更多次,您应该能够以 [^aeiou]* 开头的字符串:试试

    "^[^aeiou]*[aeiou][^aeiou]*[aeiou][^aeiou]*$"
    

    至于修复你的正则表达式,我认为你需要将栏转义为\|,所以

    grep -i "^[aeiou][^aeiou]*[aeiou][^aeiou]*$\|^[^aeiou][^aeiou]*[aeiou][^aeiou]*[aeiou][^aeiou]*$" genesis.words
    

    【讨论】:

      猜你喜欢
      • 2019-04-14
      • 1970-01-01
      • 2022-01-15
      • 1970-01-01
      • 2022-12-14
      • 1970-01-01
      • 2021-03-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多