同様の 2 つのパターン間の特定のパターンが一致しない場合は、類似した 2 つのパターン間のすべての行を削除します。

同様の 2 つのパターン間の特定のパターンが一致しない場合は、類似した 2 つのパターン間のすべての行を削除します。

タイトルは次のとおりですRemove all lines between two similar patterns, including the line of the starting pattern. if another specific pattern in between is not matched。 Google で回答を検索する他のユーザーが読みやすくなったため、短くしました。

質問について:特定のコンピュータに対して有価の株式と市場不可能な株式のリストがあります。共有を一覧表示できるすべてのコンピュータのリストを作成し、読み取れない共有を削除したいと思います。しかし、2つの問題に遭遇しました。まず、2 つの類似パターン間のすべての行を正しく削除します。第二に、特定のパターンが見つかった場合、同様の2つの単語間の行を削除しない方法です。

私のアドバイスは

Shares for DED-SHD-ED-5:
    [--- Unreadable Shares ---]
        ADMIN$
        C$
        E$
        H$
        IPC$

Shares for DED-SHD-ED-6:
    [--- Unreadable Shares ---]
        ADMIN$
        C$
        IPC$
    [--- Listable Shares ---]
        print$
Shares for DED-SHD-ED-7:
    [--- Unreadable Shares ---]
        ADMIN$
        C$
        IPC$
    [--- Listable Shares ---]
        backup      backup2
Shares for DED-SHD-ED-8:
    [--- Unreadable Shares ---]
        ADMIN$
        C$
        IPC$

Shares for DED-SHD-ED-9:
    [--- Unreadable Shares ---]
        ADMIN$
        C$
        IPC$
        VBRCatalog
    [--- Listable Shares ---]
        backup      backup2

次のコマンドを使用して、読み取れないすべての共有を削除しましたawk '/Listable Shares/,/Shares for/' input.txt。このコマンドの問題はDED-SHD-ED-8noでしたListable Shares。下のコンピュータを剥がしてからDED-SHD-ED-9販売可能な在庫を見ることができます。DED-SHD-ED-9DED-SHD-ED-8

以下の出力を参照してください(リスト内の最初のコンピュータの名前が欠落していることを知っていますが、問題ではありません)。

    [--- Listable Shares ---]
        print$
Shares for DED-SHD-ED-7:
    [--- Listable Shares ---]
        backup      backup2
Shares for DED-SHD-ED-8:
    [--- Listable Shares ---]
        backup      backup2

この問題を解決するために私の考えはawk '/Listable Shares/,/Shares for/' input.txt。まず、「共有対象」と「共有対象」の間のすべての行を削除してみました。私はより簡単な答えを見つけ、現在では理解できない複雑な答えを避けるためにフォーラムを見学しました。たとえば、このコマンドを使用しましたが、sed '/^Shares for/,/^Shares for/{//!d;};' input.txtここではsed '/Shares for/,/:/{//!d;};' input2.txtコンピュータ間の線の半分を削除しました。

出力

Shares for DED-SHD-ED-5:
Shares for DED-SHD-ED-6:
    [--- Unreadable Shares ---]
        ADMIN$
        C$
        IPC$
    [--- Listable Shares ---]
        print$
Shares for DED-SHD-ED-7:
Shares for DED-SHD-ED-8:
    [--- Unreadable Shares ---]
        ADMIN$
        C$
        IPC$

なぜコンピュータデータの半分しか削除されないのですか?なぜかわかりません。

Listable次のアイデアは、パターンがその行で一致する場合、「Shares for」と「Shares for」の間の行が削除されないように、コマンドに除外を追加することでした。次に、DED-SHD-ED-5などのデータがないコンピュータを削除しますDED-SHD-ED-7。しかし、たぶんこれが最善のアプローチではないかもしれません。 「Listable」スキーマは表示されないため、最初のスキーマの行を削除する方が良いかもしれません。

この問題を正しく処理する方法についてのヘルプと洞察力が必要です。

予想出力:

Shares for DED-SHD-ED-6:
    [--- Unreadable Shares ---]
        ADMIN$
        C$
        IPC$
    [--- Listable Shares ---]
        print$
Shares for DED-SHD-ED-7:
    [--- Unreadable Shares ---]
        ADMIN$
        C$
        IPC$
    [--- Listable Shares ---]
        backup      backup2
Shares for DED-SHD-ED-9:
    [--- Unreadable Shares ---]
        ADMIN$
        C$
        IPC$
        VBRCatalog
    [--- Listable Shares ---]
        backup      backup2

答え1

これはあなたに効果がありますか? sharesサンプル入力用に選択したファイル名。

sed -e 'tD' -e '$!N;/.\nShares/s/\n/&&/;:D' -e 'P;D' shares | awk 'BEGIN{RS="\n\n";FS="\n"}/Listable/'
Shares for DED-SHD-ED-6:
    [--- Unreadable Shares ---]
        ADMIN$
        C$
        IPC$
    [--- Listable Shares ---]
        print$
Shares for DED-SHD-ED-7:
    [--- Unreadable Shares ---]
        ADMIN$
        C$
        IPC$
    [--- Listable Shares ---]
        backup      backup2
Shares for DED-SHD-ED-9:
    [--- Unreadable Shares ---]
        ADMIN$
        C$
        IPC$
        VBRCatalog
    [--- Listable Shares ---]
        backup      backup2

デフォルトでは、改行がない場合はsed前に挿入されます。したがって、改行は次のようにShares使用できます。これで問題は簡単です。その単語を含むレコードのみを印刷します。RS="\n\n"awkListable

答え2

理解する:

  • Sharesブロックに文字列が含まれている場合は、ブロックを印刷します。Listable Shares

いったん入ると、awk通常ペアを削除できますsed

(詳細)awkアイデア:

$ cat shares.awk

NF == 0           { next }                        # skip blank lines
$1 == "Shares"    { if (print_block)              # if 1st field is "Shares"; if flag is set (==1) then ...
                       print block                # print the previous block
                    print_block = 0               # clear the flag
                    block = $0                    # initialize a new block
                    next                          # skip to next input line
                  }
/Listable Shares/ { print_block = 1 }             # if line contains "Listable Shares" then set flag
                  { block = block ORS $0 }        # append current line to end of block
END               { if (print_block)              # flush last block to stdout?
                       print block
                  }

テスト運転してみてください:

$ awk -f shares.awk input.txt
Shares for DED-SHD-ED-6:
    [--- Unreadable Shares ---]
        ADMIN$
        C$
        IPC$
    [--- Listable Shares ---]
        print$
Shares for DED-SHD-ED-7:
    [--- Unreadable Shares ---]
        ADMIN$
        C$
        IPC$
    [--- Listable Shares ---]
        backup      backup2
Shares for DED-SHD-ED-9:
    [--- Unreadable Shares ---]
        ADMIN$
        C$
        IPC$
        VBRCatalog
    [--- Listable Shares ---]
        backup      backup2

答え3

使用幸せ(以前のPerl_6)

~$ raku -e '.put for slurp.comb(/^^Shares .*? <?before ^^Shares | $ >/).grep(/Listable/);'   file 

#OR:

~$ raku -e '.put for lines.join("\n").comb(/^^Shares .*? <?before ^^Shares | $ >/).grep(/Listable/);'   file

RakuはPerlファミリーのプログラミング言語です。split正規表現パターンの破壊的な設定とは反対と見なすことができるRakuは、comb必要な要素を選択できるルーチンを提供します。上記では.comb(/^^Shares .*? <?before ^^Shares | $ >/)、入力ファイルは以下を使用してレコードを選択して複数のレコードに分割されます。

  • ^^Shares行の先頭のテキストは「share」で、
  • .*?貪欲ではないランダムな文字数、
  • <?before ^^Shares | $ >?before肯定的な予測とは、次のレコードパターンを見るとき、^^Sharesまたは$ファイル自体の前/末尾でパターンを停止することを意味します。

チェーンの2番目の操作では、ブロックを含むレコードのみを返すためにgrep使用されます。Listable

入力例:

Shares for DED-SHD-ED-5:
    [--- Unreadable Shares ---]
        ADMIN$
        C$
        E$
        H$
        IPC$

Shares for DED-SHD-ED-6:
    [--- Unreadable Shares ---]
        ADMIN$
        C$
        IPC$
    [--- Listable Shares ---]
        print$
Shares for DED-SHD-ED-7:
    [--- Unreadable Shares ---]
        ADMIN$
        C$
        IPC$
    [--- Listable Shares ---]
        backup      backup2
Shares for DED-SHD-ED-8:
    [--- Unreadable Shares ---]
        ADMIN$
        C$
        IPC$

Shares for DED-SHD-ED-9:
    [--- Unreadable Shares ---]
        ADMIN$
        C$
        IPC$
        VBRCatalog
    [--- Listable Shares ---]
        backup      backup2

出力例:

Shares for DED-SHD-ED-6:
    [--- Unreadable Shares ---]
        ADMIN$
        C$
        IPC$
    [--- Listable Shares ---]
        print$

Shares for DED-SHD-ED-7:
    [--- Unreadable Shares ---]
        ADMIN$
        C$
        IPC$
    [--- Listable Shares ---]
        backup      backup2

Shares for DED-SHD-ED-9:
    [--- Unreadable Shares ---]
        ADMIN$
        C$
        IPC$
        VBRCatalog
    [--- Listable Shares ---]
        backup      backup2

注:データが言語内部でどのように表現されるかを確認するのが役に立つことが多いので、ここに出力があります。後ろに comb別のレコードとして保存されますが、今後 greppingに必要なブロック:

~$ raku -e '.raku.put for slurp.comb(/^^Shares .*? <?before ^^Shares | $ >/);'   file
"Shares for DED-SHD-ED-5:\n    [--- Unreadable Shares ---]\n        ADMIN\$\n        C\$\n        E\$\n        H\$\n        IPC\$\n\n"
"Shares for DED-SHD-ED-6:\n    [--- Unreadable Shares ---]\n        ADMIN\$\n        C\$\n        IPC\$\n    [--- Listable Shares ---]\n        print\$\n"
"Shares for DED-SHD-ED-7:\n    [--- Unreadable Shares ---]\n        ADMIN\$\n        C\$\n        IPC\$\n    [--- Listable Shares ---]\n        backup      backup2\n"
"Shares for DED-SHD-ED-8:\n    [--- Unreadable Shares ---]\n        ADMIN\$\n        C\$\n        IPC\$\n\n"
"Shares for DED-SHD-ED-9:\n    [--- Unreadable Shares ---]\n        ADMIN\$\n        C\$\n        IPC\$\n        VBRCatalog\n    [--- Listable Shares ---]\n        backup      backup2\n\n"

https://docs.raku.org/言語/operators#Operators
https://docs.raku.org/routine/comb
https://docs.raku.org/routine/grep
https://raku.org

関連情報