コマンドを実行し、そのコマンドの出力をフィルタリングしてから、その出力の結果を読み取り、指定された要件を満たす部分だけを印刷する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
)。次に、最初から始めて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行があることを知っています。提案を印刷
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
またはl
5番目のフィールド($5
)から数をキャプチャします。
最後に、合計が0a
より大きく空でない限り、以前にキャプチャしたプロファイル行を印刷し、変数の合計を0と空の文字列にリセットします。l
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