
Ich habe eine Textdatei des folgenden Typs:
a b c d
-- -- -- --
1 ok device issue Some Action which
has to be taken which
is split into many lines
under d.
Ich habe versucht, grep für „Problem“ zu verwenden, aber es wird nur die erste Zeile von „d“ gedruckt. Die Ausgabe, die ich erhalten habe, ist:
1 ok device issue Some Action which
Ich möchte jedoch die komplette Ausgabe in d. Als ich versuchte, die Datei im CSV-Format zu speichern, wurde die zweite Zeile der Spalte d als neue Zeile angezeigt.
Bearbeiten:
Die Ausgabe wird von mehreren Geräten abgerufen, die in einer Variablen gespeichert sind, aus der ich nach denen suche, bei denen Probleme auftreten.
Antwort1
Sie benötigen hier mehrzeiliges Grepping. Dafür benötigen wir die -P
Option „PCRE aktiviert“. Da grep im Slurp-Modus durch Nullen getrennte Datensätze ausgibt, -z
entfernen wir diese mit dem Befehl tr.
$ < file grep -Pzo '.*\S.*issue.*\n(?:\h+.*\n)+' | tr -d '\0'
Antwort2
grep
verhält sich im Standardmodus wie vorgesehen. Von seiner man
Seite:
...grep sucht in jeder DATEI nach MUSTERN. MUSTER sind ein oder mehrere Muster, die durch Zeilenumbruchzeichen getrennt sind, und grep druckt jede Zeile, die einem Muster entspricht...
Es sollte also auftauchenLinienim Text, der mit einem übereinstimmt . Zeilen werden durch den Kontrollcode regex
abgegrenzt , der das Verhalten erklärt, das Sie sehen. Anders als die Verwendung der in den Antworten genannten Option. Angenommen, „Problem“ ist der reguläre Ausdruck, den Sie abgleichen möchten (ersetzen Sie ihn durch oder oder , wenn das das ist, was Sie tatsächlich abgleichen möchten); und dass die Spalte „Korrekturmaßnahme“ maschinengeneriert und konsistent ist, d. h. immer 4 Zeilen umfasst, könnten Sie auch einfach ausführen, um zu speichernnewline
-z
'Device Degraded'
'\sDegraded'
'\sError'
grep -A 3 '\sissue' > issues
nur die Zeilen, die Sie interessierenin eine Datei. Sie müssen in der Lage sein, eine Ausgabe zu generieren, die wie folgt aussieht:
1 ok device issue Some Action which
has to be taken which
is split into many lines
under d.
--
10 ok device issue Some Action which
has to be taken which
is split into may lines
under d.
--
211 ok device issue Some Action which
has to be taken which
is split into many lines
under d.
Weitere Informationen zur Funktion dieser Optionen finden Sie auf der Manpage von grep.
Antwort3
Angenommen, ein „Datensatz“ in der Eingabedatei ist genau wie vom OP bereitgestellt:
$ sed '/issue/!d; :a; n; /^[0-9]\{1,\} /d; $!ba' file
1 ok device issue Some Action which
has to be taken which
is split into many lines
under d.
$
Antwort4
Dies könnte das sein, was Sie wollen, indem Sie ein beliebiges awk in einer beliebigen Shell auf jeder UNIX-Box verwenden:
$ cat tst.awk
/^[0-9]/ { prt() }
{ rec = rec $0 ORS }
END { prt() }
function prt() {
if ( rec ~ regexp ) {
printf "%s", rec
}
rec = ""
}
.
$ awk -v regexp='issue' -f tst.awk file
1 ok device issue Some Action which
has to be taken which
is split into many lines
under d.