【问题标题】:How to match more than one pattern and delete a line using sed?如何匹配多个模式并使用 sed 删除一行?
【发布时间】:2015-11-28 17:26:48
【问题描述】:

我在文件中有一行如下所示

abcd    x  10.10.10.10

有时同一行可能有一些额外的字段,如下所示

abcd    123  AB  x  10.10.10.10

所以现在我必须从文件中删除这一行。我的匹配模式是在一行中搜索 abcd、x 和 10.10.10.10 并将其删除,因为这些是唯一的固定值。有没有办法将多个模式与逻辑和 sed 匹配并删除该行?我尝试过使用正则表达式,但由于这里的模式并不总是相同,所以这不起作用。我需要一个 sed 的解决方案。我试图搜索其他网站和*。找不到任何适合我的解决方案。

【问题讨论】:

  • 我得到了答案,这将起作用 sed -i -r '/^abcd.*x.*10.10.10.10/d' file
  • 不,这甚至不会接近工作。在您发布的示例输入上尝试它,并考虑它会产生错误匹配的所有多种方式(例如,输入行是abcdefghi red hexadecimal 20131091031071050917 banana)。您没有说这些字符串是否必须以特定顺序出现 - 是吗?

标签: regex bash sed


【解决方案1】:

这是 awk 的工作,而不是 sed:

$ cat tst.awk
BEGIN {
    split("abcd x 10.10.10.10",flds)
    for (idx in flds) {
        targets[flds[idx]]
    }
}
{
    delete cnt
    for (i=1;i<=NF;i++) {
        cnt[$i]++
    }

    for (fld in targets) {
        if (cnt[fld] == 1) {
            delete cnt[fld]
        }
    }

    for (fld in cnt) {
        # If we reach here then one or more of these conditions is true:
        # a) there was a field that is not one we targetted
        # b) there was a target field that occurred multiple times
        # c) a target field was missing
        print
        next
    }
}

$ awk -f tst.awk file
abcd    123  AB  x  10.10.10.10

由于 awk 与 sed 一样可用于所有 UNIX 安装,因此没有理由强迫自己尝试为此使用 sed。

【讨论】:

    【解决方案2】:

    这可能对你有用(GNU sed);

    sed -r 'h;s/$/\nabcd x 10.10.10.10/;ta;:a;s/(.+)(.*\n.*)\<\1\>/\2/;ta;/^\s*\n\s*$/d;x' file
    

    这会复制当前行。然后将必填字段附加到由换行符分隔的行尾。使用替换和反向引用,匹配字段将从模式空间中删除,直到无法进行进一步匹配。如果剩余的字符串只包含零个或多个由换行符分隔的空格,这将标识要删除的行,否则将保留该行以便恢复副本。

    【讨论】:

      最近更新 更多