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スクリプトも必要です。

私はこれがすべて初めて完全に立ち往生しています。助けてください!

**編集**明確にするためにボラティリティフレームワークを使用しようとしています。現在入手可能な構成ファイルを見ています。正確な出力は次のとおりです。

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行あります。次に、同じプロファイルの2つの値とゼロで始まらない数字でパターンを定義します(したがって、前にゼロがある値は失敗します)。一致するものがある場合は、パターンを参照プロファイル番号に置き換えてp印刷します(オプションでデフォルト出力を無効にしている間-n)。次に、最初から始めてD2行がある場合は、前の行を減らします。

課題の更新に基づく更新

お客様が提供した実際のシナリオについては、別のアプローチを提案します。

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;//d2行目にもプロセスがあるかどうかを確認するには、上記とまったく同じです。
  • スクリプトのこの時点で、私たちはプリルフの提案があり、その後にそれぞれゼロ以外のプロセス数を持つ2行があることを知っています。提案を印刷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ない場合は、次の行を取得して同じチェックを実行し、成功するとヘッダーを印刷します。

答え3

awkを使用してください:

注:input.txtこれはテスト用のサンプル入力を含むテキストファイルです。 comamndの出力をこの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テスト用のサンプル入力を含むテキストファイル。 comamndの出力をこのawkスクリプトに直接パイプすることができます。

これはawk、1つ以上のスペースを使用することを意味します。または左角かっこはフィールド区切り文字として機能します。これは、5番目のフィールド$ 5に関連するプロセスまたはモジュールの数が含まれることを意味します。

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

「PsA」または「PsL」で始まる行の場合、それぞれ変数aまたはl5番目のフィールド($5)から数をキャプチャします。

最後に、合計が0aより大きく空でない限り、以前にキャプチャしたプロファイル行を印刷し、変数の合計を0と空の文字列にリセットします。lppalp

または、提案されたプロファイル名のみが必要な場合(プロファイル行の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

関連情報