BASH スクリプト - 出力の読み取りと値による切り取り

BASH スクリプト - 出力の読み取りと値による切り取り

コマンドを実行し、そのコマンドの出力をフィルタリングし、その出力の結果を読み取り、指定された要件を満たすセクションのみを印刷する BASH スクリプトを作成しようとしています。

例えば:

元のコマンドの出力を次のように削減することができました。

Profile: 1
PsA of Profile 1: 13
PsL of Profile 1: 15
Profile: 2
PsA of Profile 2: 0
PsL of Profile 2: 0

各プロファイル セクションを個別に読み取り、PsA 値と PsL 値が 0 を超えるプロファイル番号のみを出力する BASH スクリプトを作成しようとしています。

わかりやすくするために、出力はプロファイル値のみにする必要があります。この例では、1 で、2 は破棄されます。

私がやろうとしている作業のため、BASH スクリプトである必要もあります。

私はこのすべてに関してまったくの初心者で、完全に行き詰まっています。助けてください!

** 編集 ** わかりやすくするために、私は Volatility Framework を使って作業しようとしています。取得できるプロファイルを確認していますが、現時点では正確な出力は次のようになります。

Profile suggestion (KDBGHeader): WinXPSP3x86
PsActiveProcessHead           : 0x8055a158 (31 processes)
PsLoadedModuleList            : 0x80553fc0 (122 modules)
Profile suggestion (KDBGHeader): WinXPSP2x86
PsActiveProcessHead           : 0x8055a158 (31 processes)
PsLoadedModuleList            : 0x80553fc0 (122 modules)

必要なのは、スクリプトで PsActiveProcessHead と PsLoadedModuleList (PsA と PsL) をチェックすることです。具体的には、見つかったプロセスとモジュールの数です。括弧で示されている両方の数が 0 より大きい場合は、プロファイルの提案を出力します。プロファイルの提案は 1 つである場合もあれば、複数ある場合もあります。モジュールとプロセスの両方が 0 より大きいプロファイルが見つかった場合は、スクリプトでそのプロファイルを出力する必要があります。

元の質問が不明瞭で申し訳ありません。質問をもっとシンプルにして回答を適応させようとしましたが、まだ苦労しています。ごめんなさい!

(念のため、上記は出力形式の例に過ぎず、常に両方の数字が 0 より大きいとは限らず、2 つ以上のプロファイル提案がある場合もあります)

答え1

sedスキームと一緒に使用できますN;D:

sed -n 'N;s/PsA\( of Profile \([0-9]*\): \)[^0].*\nPsL\1[^0].*/\2/p;D'

N次の行を追加するので、パターン スペースには常に 2 つあります。次に、同じプロファイルの両方の値と、ゼロで始まらない番号 (先頭にゼロがある値は失敗します) を使用してパターンを定義します。一致した場合は、パターンを参照されたプロファイル番号で置き換えて を出力pします (オプションによってデフォルトの出力が無効になっている間) -n。次に、 からやり直しD、2 つの行がある場合は前の行を減らします。

質問の更新に応じて更新

あなたが示した現実世界のシナリオに対して、私は別のアプローチを提案します:

sed -n '/Profile suggestion/!d;h;n;/(0/d;n;//d;g;p' yourfile

説明:

  • /Profile suggestion/!d意味: プロファイルの提案ではない行をすべて削除します。ここでスクリプトを停止して、次の行に進みます。
  • hプロフィールの提案を保留スペースにコピーして、必要に応じて印刷できるようにします。
  • n次の行に進みます。コマンド-nのオプションにより、現在の行は印刷されません。sed
  • /(0/dパターンが見つかった場合(0、このサイクルを削除します。これはプロセスがないことを意味するためです。
  • n;//d上記と全く同じように、2行目にもプロセスがあることを確認します
  • スクリプトのこの時点で、2行続くprilfeの提案があり、それぞれに0以外の数のプロセスがあることがわかります。gホールドスペースをパターンスペースにコピーして、p提案を印刷できます。

答え2

awk -F": " '
    $0~/^PsA/ && $2 > 0 
    {
        getline; 
        if($2 <= 0) next; 
        sub(/[^0-9]*/, "", $1); 
        print $1
     }' data

PsAこれが見つかったときに最初に来ると仮定してPsL、次のテキスト行 ( getline) を取得し、値が 0 より大きいかどうかを確認します。

PsAこれが成功したら、レコードPsL自体がプロファイル名を保持しているという事実を利用します 。これを行から取得して印刷します。


あなたの編集に基づいて:

awk -F": " '
    $0~/^Profile/ && h=$0 {next} 
    $1~/^PsA/ && $2~/\([^0]/ {
        getline; 
        if ($2~/\([^0]/) print h
    }' data

現在の行が で始まる場合はProfile、ヘッダー全体を保存して次の行に進みます。

最初のフィールドが で始まりPsA、括弧内が 0 でない場合は、次の行を取得して同じチェックを実行し、成功した場合はヘッダーを出力します。

答え3

awk の使用:

注:input.txtは、テスト用のサンプル入力を含むテキスト ファイルです。代わりに、コマンドの出力をこの awk スクリプトに直接パイプすることもできます。

$ awk -F' +|\\(' '/^Profile/ {p=$0};
                  /^PsA/ {a=$5};
                  /^PsL/ {l=$5};
                  a > 0 && l > 0 && p {print p; p=""; a=0; l=0}' input.txt 
Profile suggestion (KDBGHeader): WinXPSP3x86
Profile suggestion (KDBGHeader): WinXPSP2x86

input.txtテスト用のサンプル入力を含むテキスト ファイルです。代わりに、コマンドの出力をこの awk スクリプトに直接パイプすることもできます。

これはawk1つ以上のスペースを使用するように指示しますまたはフィールド区切りとして開き括弧を使用します (つまり、5 番目のフィールド $5 には、関連するプロセスまたはモジュールの数が含まれます)。

awk スクリプトは入力ファイルを読み取り、「Profile」で始まる行については、行全体 ( $0) を変数 にキャプチャしますp

「PsA」または「PsL」で始まる行の場合、 5 番目のフィールド ( )からカウントがそれぞれ変数aまたはにキャプチャされます。l$5

最後に、aとが両方ともl0 より大きく、pが空でない場合は、以前にキャプチャしたプロファイル行を出力しp、変数aとをlゼロとp空の文字列にリセットします。

あるいは、提案されたプロファイル名のみが必要な場合(これもプロファイル行の 5 番目のフィールドに含まれています):

$ awk -F' +|\\(' '/^Profile/ {p=$5};
                  /^PsA/ {a=$5};
                  /^PsL/ {l=$5};
                  a > 0 && l > 0 && p {print p; p=""; a=0; l=0}' input.txt 
WinXPSP3x86
WinXPSP2x86

関連情報