【问题标题】:How to print words who contains two "z" or two "w" (bash)如何打印包含两个“z”或两个“w”的单词(bash)
【发布时间】:2019-12-15 21:35:33
【问题描述】:

我正在尝试打印 /usr/share/dict/words 中包含两个“w”或两个“z”的单词。单词中的“w”或“z”在哪里并不重要。 我试过了,但它不能正常工作:

cat /usr/share/dict/words | grep ".+([wz]).+\1"
cat /usr/share/dict/words | grep ".*([wz]).*\1"
cat /usr/share/dict/words | grep "z{2}|w{2}"
cat /usr/share/dict/words | grep "z.*z|w.*w"
cat /usr/share/dict/words | grep "z.?z|w.?w"
cat /usr/share/dict/words | grep "z[^z].*z|w[^w].*w"

【问题讨论】:

  • 如果你有一个正则表达式,你会想使用 egrep
  • 我不同意近距离投票者的观点,并希望他们能提供比敷衍的按钮点击更完整的解释。
  • 您只想要"contains two "w" or two "z" 还是"contains two (or more) "w" or two (or more) "z"? (您与 grep "z.*z|w.*w" 关系密切,可以用作 grep 'z.*z\|w.*w'
  • only "包含两个 "w" 或两个 "z" : "pizza" OK "pizzazz" not OK "awkward" OK

标签: shell grep


【解决方案1】:

带有 ERE 支持的 -E 标志:

grep -E 'w.*w|z.*z' /usr/share/dict/words
grep -E '([wz]).*\1' /usr/share/dict/words

关于第二个,一些实现可能不支持 ERE 中的反向引用,所以不要依赖它,不要指望它在任何地方都能工作。

【讨论】:

  • grep 'z.*z\|w.*w' 的 BRE 也可以使用 :)
  • 有点琐事,在我的/usr/share/dict/american 中有1546 包含2 个'w' 或2 个'z' "Zyzzyva /ˈzɪzɪvə/ is a genus of tropical American weevils often found in association with palms. It is a snouted beetle." :) 的单词
  • @DavidCRankin BRE 中的交替是一个 GNU 扩展。如果可移植性很重要,则需要 ERE 版本。
【解决方案2】:

要查看至少有 2 个 ws 或 2 个 zs 的单词,您可以这样做:

egrep "(z.*z|w.*w)" /usr/share/dict/words

说明:匹配任何包含至少 2 个 zs 或至少 2 个 ws 的行

要查看正好 2 ws 或 zs 的单词,您可以这样做:

egrep "^([^z]*z[^z]*z[^z]*|[^w]*w[^w]*w[^w]*)$" /usr/share/dict/words

说明:匹配任何以 0 个或多个非 z/w 字母开头、后跟一个 z/w、后跟零个或多个非 z/w 字母、后跟一个 z/w 和另一组零个或多个非 z/w 字母。简而言之,确保恰好有 2 个 zs 或 ws。

【讨论】:

  • 您的解决方案效果很好,谢谢您的解释;)
【解决方案3】:

要匹配准确两个 w 或 z(不是三个或更多)的单词,您可以使用:

grep -E '^[^w]*w[^w]*w[^w]*$|^[^z]*z[^z]*z[^z]*$' /usr/share/dict/words

【讨论】:

    【解决方案4】:

    awk怎么样:

    awk 'gsub("w", "&") >= 2 || gsub("z", "&") >= 2' /usr/share/dict/words
    

    【讨论】:

    • 在这两个方面都应该是>= 2。 (除非他只想要 2 个——不清楚)
    • @DavidC.Rankin 感谢您的评论。我确实想知道哪个应该是合适的。现在我同意使用>= 会更安全。我已经更正了我的答案。
    • 我在请求澄清的原始问题下添加了一条评论。我怀疑他们想要两个或更多,但他们的意思是两个并不超出可能性范围。我猜他们可以选择。
    • 正好是两个。如果我将>= 更改为==,则效果很好。谢谢。
    • @Dj-liwood 感谢您的反馈。如果我的答案足够可读,我很高兴您可以根据要求对其进行修改。 BR。
    【解决方案5】:

    我个人觉得“两种不同的表达方式”的方法更具可读性:

    $ grep -e 'z.*z' -e 'w.*w' /usr/share/dict/words | head
    abuzz
    adazzle
    Albizzia
    amidoazobenzene
    amidoazobenzol
    aminoazobenzene
    arrowweed
    arrowwood
    arrowworm
    athwarthawse
    

    【讨论】:

      猜你喜欢
      • 2016-05-15
      • 2017-12-31
      • 2018-04-19
      • 1970-01-01
      • 1970-01-01
      • 2019-03-11
      • 2015-11-22
      • 2019-03-24
      • 1970-01-01
      相关资源
      最近更新 更多