1

私の質問は、最初に発生する 3 つのパターンから決定し、最初のパターンの前のすべてを削除し、最後のパターンの後のすべてを同様に削除することです。

上記のパターンをすべて削除するには、次のコマンドを使用できることを認識しています。

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

grep -E -m1 "pattern1|pattern2|pattern3" 最初のパターンを構成する行を出力します。このコマンドの出力を のいくつかのバリアントにフィードする必要があると思いますが、sedその方法はわかりません。

  1. パターン1
  2. パターン2
  3. パターン3

Line1 これは例として意味のないサンプル行です 無視してください
Line2 は例を示すことのみを目的としています PATTERN2 をすべての人に明確にする
ため
にクエリをすべて明確にして
くださいLine5 これは例としての意味のないサンプル行です 無視してください
Line6 は例を示すためだけです パターン 1 すべての人にクエリを明確にするため
Line7 これはサンプル行です たとえば何の意味もありません
Line8 のみを意味します 無視してください私のクエリをすべての行に明確にするためにパターン2の例を与えるため、
これはサンプル行です。たとえば、意味はありません無視してください
Line10 は、クエリの例をすべての人に明確にするためのパターン 3 を提供するため
だけのもの Line11 は、すべての人に私のクエリを明確にするためのパターン 1 の例
を提供するため
だけのものです。私のクエリをすべての人に明確にするためのパターン3の例
Line14は、私のクエリをすべての人に明確にするための例を示すことのみを目的としています

望ましい出力:

最初のパターンが PATTERN2 で、pattern3 が 3 つのパターンの最後のパターンである場合、次のような出力が必要になります。

Line2 は、私のクエリをすべての人に明確にするための例 PATTERN2 を提供するためのものです。
Line3 これは、例として意味のないサンプル行です。無視
してください
。意味のない例は無視してくださいLine6 は、私のクエリをすべての人に明確にするためのパターン 1 の例を提供すること のみ
を意図しています
Line7 これはサンプル行です 。これはサンプル行です。意味はありません。Line10 は無視してください。パターン 3 の例を示して、クエリをすべての人にわかりやすくするためのものです


Line11 は、すべての人にクエリを明確にするための PATTERN2 の例を提供すること
のみを目的としています Line12 は、すべての人にクエリを明確
にするためのパターン 1 の例を提供することのみを目的としています。

4

2 に答える 2

2

sed は、1 行の単純な置換には優れたツールですが、それ以外の場合は 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 に答える