【问题标题】:How can I delete everything after the next word matching a regular expression?如何在匹配正则表达式的下一个单词之后删除所有内容?
【发布时间】:2016-10-11 17:20:54
【问题描述】:

我正在尝试在匹配模式之后删除行尾的所有字段,并且我还想将下一个字段打印到该模式。 可能有多种模式。

示例:

one two three four five six seven
robin mike luke jennifer jessie mark
...

模式:

two
jennifer

输出:

one two three
robin mike luke jennifer jessie
...

我试过了:

cat file | sed -E 's/(.+ two|jennifer) .+/\1 /'
one two
robin mike luke jennifer

但我错过了下一个字段。

【问题讨论】:

    标签: bash awk sed


    【解决方案1】:

    由于您似乎可以访问 GNU 工具,我建议您使用 grep:

    grep -Eo '.*\b(two|jennifer)(\s+\S+)?' file
    

    这匹配直到字段“two”或“jennifer”的任何内容,然后是下一个字段(如果存在)。感谢@123 提供有用的建议。

    -o 只打印行的匹配部分,-E 启用扩展正则表达式。

    【讨论】:

    • 将匹配包含两个或 jennifer 的字段。如果第一个或最后一个字段,编辑也会失败。也许grep -oP '.*\b(two|jennifer)(\s\S+)?'
    • 我再次编辑了,谢谢。我想-P 不是必需的?
    • 不,只是习惯使用它而不是-E
    • 如果没有匹配,它什么也不打印。再说一遍,也许这是需要的?
    • @JamesBrown 如果不是grep -Po '.*\b(two|jennifer)(\s+\S+)?|^.*',则轻松修复@
    【解决方案2】:

    在 awk 中:

    $ awk 'NR==FNR{a[$1];next}{for(i=1;i<=NF;i++) if($i in a) NF=((i+1)>NF?NF:(i+1))} 1' pats ex
    one two three
    robin mike luke jennifer jessie
    

    其中pats 是模式文件,ex 是示例记录文件。解释:

    NR==FNR {                           # process pattern file
        a[$1]                           # store all patterns into a hash
        next                            # skip to next record
    }
    {
        for(i=1;i<=NF;i++)              # for each word in example file record
            if($i in a)                 # check if found in a
                NF=((i+1)>NF?NF:(i+1))  # if found, cut record after the next word
    } 1                                 # print the record
    

    当前程序检查是否在哈希 a 中找到单词。这意味着在处理第一条记录时,它会检查twojennifer。如果这不是可取的,可以通过替换来轻松处理

    • 第二行:a[$i]a[FNR]=$1
    • 第七行:if($i in a)if($i==a[FNR])

    【讨论】:

      猜你喜欢
      • 2019-11-12
      • 2014-12-30
      • 2018-07-18
      • 2018-12-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-26
      相关资源
      最近更新 更多