【问题标题】:How to delete a line if a string is present in the line twice如果行中出现两次字符串,如何删除该行
【发布时间】:2018-11-29 08:09:37
【问题描述】:

我需要删除在同一行中包含两次字符串的所有行。

例子:

hi 
hi hello
hi hello hey
hey hi:hello:hi #delete this line

结果:因为最后一行包含两次“hi”。字符串没有被任何固定的分隔符正确分隔,有时它是空格或逗号或冒号,或者可以是任何东西。

hi 
hi hello
hi hello hey

如果它是基于列的固定数据,我可以使用:(粗略的想法)

awk '{for(i=1;i<=NF;i++) if($i ~/hi/) c++ ;if(c<2) print $0}'

【问题讨论】:

  • 为什么第二行没有删除?它包含字符串h 两次。和l 两次。第三行也包含两次字符串he
  • @monk,我已经发布了解决方案,它会将字段分隔符设置为 `:#`,以防万一您有更多字段分隔符,那么您也可以在代码中提及它们。
  • @jeremysprofile 请看下面的单行字。
  • @karakfa,我承认 =)

标签: bash awk sed


【解决方案1】:

sed 可能会更容易

$ sed -E '/(\b\w+\b).*\b\1\b/d' file

如果一个单词重复删除该行。您必须使用单词边界来定义单词,否则任何重复的字符都将匹配正则表达式。

【讨论】:

  • 这对我不起作用。我正在使用空格分隔的单词。
  • 空格也是单词边界。您是否尝试过上面发布的示例?也许您的sed 不支持反向引用。
  • @karakfa 或者可能是他们的 sed 实现不支持单词边界。我知道 GNU sed 支持它,但不确定其他版本
  • 另外,\1 之后需要另一个单词边界,否则 hihim 之类的单词会匹配。你也可以使用 grep 来提高速度。grep -vE '(\b\w+\b).*\1\b'
  • @Sundeep,右边界不是捕获的一部分,也需要添加到反向引用中。
【解决方案2】:

请您尝试关注一下。

awk -F'[ :#]' '{for(i=1;i<=NF;i++){if(++a[$i]>1){delete a;next}};delete a} 1'   Input_file

输出如下。

hi
hi hello
hi hello hey

【讨论】:

    【解决方案3】:

    你可以这样做:

    awk -F'[ :;,]' '{ delete seen; for(i=1; i<=NF; i++) {seen[$i]++} # parse words and store in a hash             
           for(i in seen) if(seen[i] == 2) {next}                    # skip line if it has a word that is repeated two times
         }1' file
    

    【讨论】:

    • 我想我用 8 或 9 秒击败了你 :) 我们都采用了相同的方法,唯一的问题是我采用了更多的字段分隔符,因为 OP 告诉它可能有几个不同的分隔符。我留给 OP 做决定,干杯,伙计。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-20
    • 1970-01-01
    • 1970-01-01
    • 2020-06-16
    • 2013-12-15
    • 2019-04-02
    • 1970-01-01
    相关资源
    最近更新 更多