1

我的问题是从首先出现的三个模式中做出决定,然后删除第一个模式之前的所有内容,并同样删除最后一个模式之后的所有内容。

我知道可以使用以下命令删除以上模式的所有内容:

sed -n '/pattern/,$p' input  

grep -E -m1 "pattern1|pattern2|pattern3" 将打印包含第一个模式的行,我想我必须将此命令的输出提供给一些变体,sed但不知道该怎么做。

  1. 模式1
  2. 模式2
  3. 模式3

Line1 这是一个示例行,例如没有任何意义 请忽略
Line2 仅用于给出示例 PATTERN2 以使我的查询对所有人都清楚
Line3 这是一个示例行例如没有任何意义 请忽略
Line4 仅用于给出示例 pattern1 到让我的查询对所有人都清楚
Line5 这是一个示例行,例如没有任何意义 请忽略
Line6 仅用于给出示例 pattern1 以使我的查询对所有人都清楚 Line7
这是一个示例行例如没有任何意义 请忽略
Line8 仅表示为了给出一个示例 pattern2 以使我的查询对所有
Line9 都清楚这是一个示例行,例如没有任何意义,请忽略
Line10 仅用于
提供
示例 pattern3 以使我的查询对所有人都
清晰一个示例 pattern3 使我的查询对所有人都清楚
Line14 仅用于举例说明我的查询对所有人都清楚

期望的输出:

如果第一个模式是 PATTERN2 并且 pattern3 是三个模式中的最后一个模式,那么下面将是所需的输出:

Line2 仅用于提供示例 PATTERN2 以使所有查询都清楚
Line3 这是示例行,例如没有任何意义 请忽略
Line4 仅用于提供示例 pattern1 以使所有查询都清楚
Line5 这是示例行没有任何意义的示例 请忽略
Line6 仅用于给出示例 pattern1 以使所有查询都清楚 Line7
这是示例行例如没有任何意义 请忽略
Line8 仅用于给出示例 pattern2 以使所有查询都清楚
Line9这是一个示例行,例如没有任何意义请忽略 Line10 仅用于提供示例 pattern3 以使我的查询对所有人都清楚
Line11 仅用于提供示例 PATTERN2 以使我的 查询
清楚

4

2 回答 2

2

sed 是用于在单行上进行简单替换的出色工具,但对于其他任何事情,只需使用 awk。您没有提供任何示例输入或预期输出或任何有关“模式”含义的信息,所以这是一个未经测试的猜测,但也许它对您有用:

awk -v pats='pattern1|pattern2|pattern3' '
    { data[NR] = $0 }
    $0 ~ pats { if (start) end=NR; else start=NR }
    END{ for (i=start; i<=end; i++) print data[i] }
' file

评论版本:

awk -v pats='pattern1|pattern2|pattern3' # or-separated list of patterns to be matched                            
    { data[NR] = $0 }                    # save current line in an array indexed by line number
    $0 ~ pats {                          # IF the current line matches any of the target patterns THEN
        if (start)                       #    IF the start line number is already recorded THEN
            end=NR;                      #        remember the current line number as the last one on which one of the patterns exists
        else                             #    ELSE
            start=NR                     #        remember the current line number as the first one on which one of the patterns exists
                                         #    ENDIF
    }                                    # ENDIF
    END{                                 # Once all of the file has been read into the array
        for (i=start; i<=end; i++)       # Loop through the array, starting at the first line on which one of the patterns was found
                                         # and ending on the last line on which one of the patterns was found
            print data[i]                #     Print the contents of the array at each line number in the loop.
    }
' file
于 2013-09-30T15:20:51.670 回答
1

正如您所展示的,这将在第一次出现之前删除任何内容:

sed -n '/pattern/,$p' file

所以我们可以获取它的输出,反转它并再次应用程序。然后反转它的输出我们得到第一个和最后一个匹配之间的所有文本:

seq 10 | sed -n '/4\|7/,$p' | tac | sed -n '/4\|7/,$p' | tac
4
5
6
7

我们可以把它放到一个函数中:

after() { sed -n '/'"$1"'/,$p'; }
between() { after "$1" | tac | after "$1" | tac; }
seq 10 | after '4\|7'
echo ===
seq 10 | between '4\|7'
4
5
6
7
8
9
10
===
4
5
6
7
于 2013-09-30T15:28:31.287 回答