【问题标题】:Match strings with certain number of unique characters in bash在bash中匹配具有一定数量唯一字符的字符串
【发布时间】:2020-06-18 12:00:33
【问题描述】:

我需要删除文件中包含少于 4 个唯一字符的所有字符串

输入:

hello
cabby
pabba
lokka
lappa
coool
apple

预期输出:

hello
cabby
lokka
apple

我试图想出一个正则表达式来做到这一点,但我想不出它怎么可能。 我确实找到了一个看起来很有希望的sed 命令,它删除了所有重复的字符。但是,我不确定如何编写 sed 来测试程序是否返回 4 个字符,如果返回,则匹配原始字符串。 sed ':1;s/\(\(.\).*\)\2/\1/g;t'

【问题讨论】:

  • 我怀疑你可以用sed 做到这一点。即使在grep 中使用 PCRE 正则表达式,纯正则表达式解决方案看起来也很笨拙,请参阅 grep -vP '^(?:(.)\1*(?:(?!\1)(.)(?:\1|\2)*(?:(?!\1|\2|3)(.)(?:\1|\2|\3)*)?)?)?$' file (demo)。使用awk

标签: regex string bash awk sed


【解决方案1】:

使用gnu awk

awk 'BEGIN{FS=""} {
unq=0; delete seen; for (i=1; i<=NF; i++) if (!seen[$i]++) unq++} unq > 3' file

hello
cabby
lokka
apple

FS="" 在 awk 中将每个字符分成一个单独的字段。

【讨论】:

  • 等等,不,你是对的,在这种情况下,awk 比我的文件快 4.2 秒。
  • 是的,我在 36988000 行文件上测试了 sedawk 解决方案。 awk 花了大约 1 分钟完成,但 sed 仍在运行最后 8 分钟并消耗大量 CPU :(
  • 也许提到stackoverflow.com/a/31135987/3220113。我同意您的答案更具可读性(而且速度更快)。
  • 感谢瓦克特。我明确表示它需要 gnu awk
  • @ersan:您可以使用:awk 'BEGIN{FS=""} {s=""; unq=0; delete seen; for (i=1; i&lt;=NF &amp;&amp; $i !~ /^[[:blank:]]$/; i++) {s = s $i; if (!seen[$i]++) unq++}} unq &gt; 3 {print s}' file 仅处理第一个文件。
【解决方案2】:

您尝试过sed ':1;s/\(\(.\).*\)\2/\1/g;t',请将t 替换为t1
在您的命令之前,将当前行复制到 Hold 空间中。
在您的命令之后,将包含至少 4 个字符的行替换为原始行。
现在确保只打印至少包含四个字符的行。

echo 'hello
cabby
pabba
lokka
lappa
coool
apple' | sed -nE 'h;:1;s/(.)(.*)\1/\1\2/g;t1;/.{4}/x;/.{4}/p'

【讨论】:

    猜你喜欢
    • 2015-04-30
    • 1970-01-01
    • 1970-01-01
    • 2011-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多