Ich versuche, ein BASH-Skript zu erstellen, das einen Befehl ausführt, die Ausgabe dieses Befehls filtert und dann die Ergebnisse dieser Ausgabe liest, um dann nur die Abschnitte zu drucken, die die gegebene Anforderung erfüllen.
Zum Beispiel:
Es ist mir gelungen, die Ausgabe des ursprünglichen Befehls so zu reduzieren, dass die Ausgabe folgendermaßen aussieht:
Profile: 1
PsA of Profile 1: 13
PsL of Profile 1: 15
Profile: 2
PsA of Profile 2: 0
PsL of Profile 2: 0
Ich versuche, ein BASH-Skript zu schreiben, das jeden Profilabschnitt einzeln liest und nur die Profilnummern druckt, deren PsA- und PsL-Werte über 0 liegen.
Der Übersichtlichkeit halber muss die Ausgabe nur der Profilwert sein, in diesem Beispiel also 1, wobei 2 verworfen wird.
Aufgrund der Arbeit, die ich zu erledigen versuche, muss es auch ein BASH-Skript sein.
Ich bin ein echter Neuling in all dem und stecke völlig fest. Bitte helfen Sie!
** BEARBEITEN ** Der Übersichtlichkeit halber versuche ich, mit dem Volatility Framework zu arbeiten. Ich schaue mir die Profile an, die abgerufen werden können, und derzeit sieht die genaue Ausgabe folgendermaßen aus:
Profile suggestion (KDBGHeader): WinXPSP3x86
PsActiveProcessHead : 0x8055a158 (31 processes)
PsLoadedModuleList : 0x80553fc0 (122 modules)
Profile suggestion (KDBGHeader): WinXPSP2x86
PsActiveProcessHead : 0x8055a158 (31 processes)
PsLoadedModuleList : 0x80553fc0 (122 modules)
Ich brauche das Skript, um PsActiveProcessHead und PsLoadedModuleList (PsA und PsL) zu überprüfen – insbesondere die Anzahl der gefundenen Prozesse und Module. Wenn BEIDE, die in Klammern angezeigt werden, über 0 liegen, wird der Profilvorschlag gedruckt. Es kann 1 Profilvorschlag geben, es können auch mehrere sein – ich brauche das Skript, um alle gefundenen Profile auszugeben, die sowohl Module als auch Prozesse mit einer Anzahl über 0 aufweisen.
Ich entschuldige mich für die unklare ursprüngliche Frage. Ich habe versucht, sie einfacher zu machen und die Antworten anzupassen, aber es fällt mir immer noch schwer. Tut mir leid!
(Um es ganz klar zu sagen: Das Obige ist nur ein Beispiel für das Ausgabeformat. Es werden nicht immer beide Zahlen über 0 enthalten und es kann mehr als zwei Profilvorschläge geben.)
Antwort1
sed
Sie können mit einem Schema verwenden N;D
:
sed -n 'N;s/PsA\( of Profile \([0-9]*\): \)[^0].*\nPsL\1[^0].*/\2/p;D'
Das N
hängt die nächste Zeile an, sodass Sie immer zwei im Musterbereich haben. Dann definieren Sie einfach ein Muster mit beiden Werten desselben Profils und einer Zahl, die nicht mit Null beginnt (Werte mit führenden Nullen schlagen also fehl!). Wenn es eine Übereinstimmung gibt, ersetzen Sie das Muster durch die referenzierte Profilnummer und p
drucken Sie es aus (während die Standardausgabe per -n
Option deaktiviert ist). Beginnen Sie dann erneut mit D
und reduzieren Sie die vorherige Zeile, wenn zwei vorhanden sind.
Aktualisierung gemäß Fragenaktualisierung
Für das von Ihnen beschriebene reale Szenario schlage ich einen anderen Ansatz vor:
sed -n '/Profile suggestion/!d;h;n;/(0/d;n;//d;g;p' yourfile
Erläuterung:
/Profile suggestion/!d
bedeutet: Alle Zeilen löschen, die keine Profilvorschläge sind. Stoppen Sie das Skript hier, um mit der nächsten Zeile fortzufahren.h
kopiert den Profilvorschlag in den Wartebereich, damit wir ihn bei Bedarf ausdrucken könnenn
fährt mit der nächsten Zeile fort. Die aktuelle Zeile wird nicht gedruckt, da die-n
Option zumsed
Befehl/(0/d
löscht diesen Zyklus, wenn wir das Muster gefunden haben(0
, denn das bedeutet, dass keine Prozessen;//d
genau wie oben, um sicherzustellen, dass die zweite Zeile auch Prozesse hat- An diesem Punkt des Skripts wissen wir, dass wir einen Prilfe-Vorschlag mit zwei folgenden Zeilen hatten, jede mit einer von Null verschiedenen Anzahl von Prozessen.
g
kopiert den Hold-Speicherplatz zurück in den Musterspeicherplatz, sodass wirp
den Vorschlag ausdrucken können
Antwort2
awk -F": " '
$0~/^PsA/ && $2 > 0
{
getline;
if($2 <= 0) next;
sub(/[^0-9]*/, "", $1);
print $1
}' data
Angenommen, „ come“ ( PsA
kommt zuerst) PsL
, wenn wir dies finden, greifen Sie zur nächsten Textzeile ( getline
) und prüfen Sie, ob der Wert größer als 0 ist.
Wenn dies erfolgreich ist, nutzen Sie die Tatsache, dass der PsA
Datensatz und PsL
selbst den Profilnamen enthalten. Nehmen Sie diesen aus der Zeile und drucken Sie ihn aus.
Basierend auf Ihrer Bearbeitung:
awk -F": " '
$0~/^Profile/ && h=$0 {next}
$1~/^PsA/ && $2~/\([^0]/ {
getline;
if ($2~/\([^0]/) print h
}' data
Wenn die aktuelle Zeile mit beginnt, Profile
speichern Sie den gesamten Header und fahren Sie mit der nächsten Zeile fort.
Wenn das erste Feld mit beginnt PsA
und innerhalb der Klammern nicht 0 ist, holen Sie sich die nächste Zeile und führen Sie die gleiche Prüfung durch. Wenn dies erfolgreich ist, drucken Sie die Kopfzeile.
Antwort3
Mit awk:
HINWEIS: input.txt
ist eine Textdatei, die Ihre Beispieleingabe zum Testen enthält. Sie können die Ausgabe Ihres Befehls stattdessen einfach direkt in dieses awk-Skript weiterleiten.
$ 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
ist eine Textdatei, die Ihre Beispieleingabe zum Testen enthält. Sie können die Ausgabe Ihres Befehls stattdessen einfach direkt in dieses awk-Skript weiterleiten.
Dies weist darauf hin awk
, ein oder mehrere Leerzeichen zu verwendenodereine öffnende Klammer als Feldtrennzeichen (was bedeutet, dass das fünfte Feld, $5, die Anzahl der relevanten Prozesse oder Module enthält).
Das awk-Skript liest die Eingabedatei und erfasst bei Zeilen, die mit „Profile“ beginnen, die gesamte Zeile ( $0
) in der Variablen p
.
Für Zeilen, die mit „PsA“ oder „PsL“ beginnen, erfasst es die Anzahl in Variablen a
bzw. l
aus dem fünften Feld ( $5
).
Schließlich wird, wenn sowohl als a
auch l
größer als 0 sind und p
nicht leer ist, die zuvor erfasste Profilzeile gedruckt und die Variablen und auf Null und auf die leere Zeichenfolge p
zurückgesetzt .a
l
p
Alternativ, wenn Sie nur die vorgeschlagenen Profilnamen wünschen (die sich zufällig auch im fünften Feld der Profilzeilen befinden):
$ 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