0

問題は次のとおりです。文字列 testfile のセットを含むファイルがあります。

string2 var var33
string2 HD loop 334
000:000:7878:7878:8978
string1 var var33    
string1 HD loop
000:000:7878:7878:8978
string3 var var33
string3 HD loop4343
000:000:7878:7878:8978

「HD ループ」などの厳密なパターンが適切な行を見つけて、その行とその後にある文字列を出力する必要があります。つまり、結果は次のようになります。

string1 var var33
string1 HD loop
000:000:7878:7878:8978
4

6 に答える 6

1

おそらく、コンテキストmax_countを探しています。使用GNU grep

grep -C 1 -m 1 "HD loop" file.txt

一致する行とその後の行のみを出力する場合は、に変更-C 1-A 1ます。

編集:

grep -P -C 1 "\bHD loop\b" file.txt

編集:

grep -C 1 "[^a-zA-Z0-9_]HD loop[^a-zA-Z0-9_]" file.txt
于 2012-10-08T10:50:41.497 に答える
0

あなたはプログラムを求めているのでsed、ここにあなたが求める答えを与えるプログラムがあります

sed -n -f xfile.sed xfile.txt

ここで、xfile.txtはサンプル入力ファイルで、xfile.sed

H
/HD loop/{
  x
  p
  n
  p
  q
}
于 2012-10-08T10:23:42.870 に答える
0

sed を使用:

#!/bin/sed -nf

/HD loop$/ {
    x
    G
    N
    p
    s/.*\n\([^\n]*\)/\1/
}
h

行末($文字で示す)に「HD loop」が見つかると、コマンドブロックが実行されます。xこのコマンド ブロックは、 exchange コマンドを使用して、ホールド スペース (補助バッファー) の内容をパターン スペース (作業バッファー) の内容と交換することから始まります。後で見るように、最後の行が読み取られたホールド スペースを保持します。このG コマンドはホールド スペース (現在の行を含む) の内容をパターン スペースに追加し、Nコマンドは入力の次の行を読み取ってパターン スペースに追加します。次に、パターン空間をp指図。最後に行うことは、ホールド スペースを復元することです。これを行うには、2 つのコマンドを使用します。1 つ目は、パターン スペースから最後の行を除くすべての行を削除する代替コマンドです。次に、コマンドでスペースを保持するためにパターン スペースをコピーしますh

「HD ループ」は行が一致しなくてもホールドスペースにコピーされます。これにより、保留スペースには常に前の行の内容が含まれます。一致が見つかった後にホールド スペースを設定する方法が原因で、連続する行に表示される 2 つの一致が正しく認識されないことに注意してください。これを考慮したい場合は、特別な処理が必要です。

#!/bin/sed -nf

/HD loop$/ b next
h

:start
n

/HD loop$/ {
    x
    G
    :next
    N
    p
    s/.*\n\([^\n]*\)/\1/
    /HD loop$/ b next
    d
}
h
b start

より完全で一般的なバージョンを作成するには、最初の行に「HD ループ」が見つかった場合に何が起こるかをまず検討する必要があります。以前のバージョンでは、空の行の後に「HD ループ」行が出力されていました。これにより、実際には HD ループの前に空の行があると出力が混乱する可能性があるため、これには特別な処理を使用する必要があります。特別な処理は、sed の評価ループを独自のものを使用してオーバーライドすることです。

ループの開始を定義するコマンドでstartラベルを定義します。:次に、スクリプトの最後で、bbranch コマンドを使用してループの先頭に戻ります。sed の評価ループを完全に模倣するには、startラベルの 後の最初のコマンドがn次のコマンドになり、次の入力行をパターン空間に読み込みます。

ループを定義すると、最初の行が HD ループで始まる特殊なケースを処理できます。含まれている場合は、ホールド スペースの内容の読み込みをスキップする必要があります。これは、ホールド スペースには有用なデータが含まれていないことがわかっているためです。ホールド スペースの内容を追加するコマンドnextの直後にラベルを定義しましょう。Gを使用/HD loop/ b nextして、ホールド スペース操作をスキップし、現在の行と次の行だけを出力できます。

最初の行が「HD ループ」で始まらない場合は、n別のコマンドで置き換える前にホールド スペースに格納する必要があります。したがって、hコマンドでそれを行います。

次の特殊なケースは、2 つの「HD ループ」ラインが連続して表示される場合です。その場合、以前のバージョンのブロックの最後で、新しく読み取った行に「HD ループ」が含まれているかどうかを確認できます。含まれている場合は、単にnextラベルに戻って別の行を読み取り、それを印刷します。これを必要なだけ何度でも行うことができ、利用可能な連続した「HD ループ」ラインをいくつでも処理できます。

最後の特別なケースは、2 つの「HD ループ」行が 1 行で区切られて表示される場合です。そのままにしておくと、この場合、「HD ループ」行の間の行が 2 回印刷されます。これを処理するには、一致の直後に「HD ループ」行が見つかった場合、ホールド スペースを出力する必要がないかのように動作する必要があります。この状況は、入力の最初の行を調べているときに起こることと似ているためd、一致の最後で delete コマンドを使用して、パターン スペースをクリアし、スクリプト全体を再起動できます。行が最初の入力行であるかのように動作し、一致の後の行が「HD ループ」行である場合、ホールド スペースを出力しません。

更新: 最初の結果のみが必要な場合は、いくつかのことを単純化できます。

#!/bin/sed -nf

/HD loop$/ b next
h

:start
n

/HD loop$/ {
    x
    G
    :next
    N
    p
    q
}
h
b start

ここで、行を印刷した後に以前のすべての操作を実行する代わりに、qコマンドで終了することができます。

これが役立つことを願っています=)

于 2012-10-08T11:52:14.390 に答える
0

awkshell: _

awk '
    {
        arr[c++] = $0
    }
    END{
        for (a in arr) {
            if (arr[a] ~ "HD loop") {
                printf("%s\n%s\n%s\n", arr[a-1], arr[a], arr[a+1])
                exit
             }
        }
    }
' FILE

あまりにも多くの RAM を埋める必要のない別の実装:

awk '
    {
        if ($0 ~ "HD loop") {
            print var
            print $0
            getline
            print
            exit
        }
        else{
            var=$0
        }
    }
' FILE
于 2012-10-08T10:06:52.293 に答える
0

これはうまくいくかもしれません(GNU sed):

sed '$!N;/HD loop$/!D;$!N;p;d' file
于 2012-10-08T23:58:59.910 に答える
0
awk '{for(i=1;i<NF;i++)if($i" "$(i+1)=="HD loop"){print x;print;getline;print}};{x=$0}' your_file

以下でテスト:

> cat temp
    000:000:7878:7878:8978
    string1 var var33    
    string1 HD loop
    000:000:7878:7878:8978
    string3 var var33
    string3 HD loop4343
    000:000:7878:7878:8978

> awk '{for(i=1;i<NF;i++)if($i" "$(i+1)=="HD loop"){print x;print;getline;print}};{x=$0}' temp
    string1 var var33    
    string1 HD loop
    000:000:7878:7878:8978
于 2012-10-08T14:01:34.283 に答える