Sed extrahieren von text zwischen zwei strings
Bitte helfen Sie mir bei der Verwendung von sed.
Ich habe eine Datei wie unten.
START=A
xxxxx
xxxxx
END
START=A
xxxxx
xxxxx
END
START=A
xxxxx
xxxxx
END
START=B
xxxxx
xxxxx
END
START=A
xxxxx
xxxxx
END
START=C
xxxxx
xxxxx
END
START=A
xxxxx
xxxxx
END
START=D
xxxxx
xxxxx
END
Ich möchte den text zwischen START=EIN, ENDE.
Ich verwendet die folgenden Abfrage.
sed '/^START=A/, /^END/!d' input_file
Das problem hier ist ,
Ich bin immer
START=A
xxxxx
xxxxx
END
START=D
xxxxx
xxxxx
END
statt
START=A
xxxxx
xxxxx
END
Sed findet gierig.
Bitte helfen Sie mir in resolvng diese.
Vielen Dank im Voraus.
Kann ich AWK für die Erreichung der oben genannten?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Den
-n
option bedeutet nicht drucken standardmäßig wird; dann wird das Skript sagt " do print zwischen die Zeile mitSTART=A
und die nächstenEND
.Kann man es auch mit
awk
:(aus
man awk
auf Mac OS X).Gegeben, eine modifizierte form der Daten-Datei in der Frage:
Sich die Ausgabe mit GNU
sed
oder Mac OS X (BSD)sed
, und mit GNUawk
oder BSDawk
ist das gleiche:Hinweis, wie ich dass modifizierte Daten-Datei, so ist es einfacher zu sehen, wo die verschiedenen Datenblöcke gedruckt, kam in die Datei.
Wenn Sie ein anderes Ausgabe-Anforderung (wie etwa 'nur den ersten block zwischen START=A und ENDE', oder 'nur die Letzte ...'), dann werden Sie brauchen, um zu artikulieren, dass deutlich mehr in die Frage.
awk
und diesed
Skripte — zumindest auf meinem Rechner mit meiner Kopie der Datendatei, die Sie zur Verfügung gestellt — print 5 Blöcke von Daten zwischenSTART=A
undEND
, und die Blöcke mitSTART=B
zuEND
,START=C
zuEND
undSTART=D
zuEND
sind alle weggelassen aus der Ausgabe. Die Plattform testen Sie auf? Welche version vonsed
verwenden Sie? Welche version vonawk
verwenden Sie? (Ich bemerken Sie, dass Ihre Testdaten wiederholt wörtlich die Blöcke zwischenSTART=A
undEND
. Es wäre viel besser, wenn Sie hatten verschiedene Linien dazwischen, so dass man sehen konnte, welche Zeilen gedruckt werden.)START=A
undEND
Linien. Wenn Sie nicht möchten, dass die start-und Ende-Markierungen angezeigt werden, können Siesed
wie diese:sed -n -e '/^START=A$/,/^END$/ { /^START=A$/d; /^END$/d; p; }'
. Oder Sie könnenawk
wie diese:awk '/^START=A$/,/^END$/ { if ($0 != "START=A" && $0 != "END") print }'
(gleiche Grundidee, wenn Sie code, die Bedingung in einer Reihe von verschiedenen Möglichkeiten, wenn gewünscht)Basic version ...
Stabilere version...
,
bedeutet in der sed-Muster-string?,
zwischen zwei teilen eines verschiedenen definiert durch zwei regexes, so dass die Linien zwischen dem ersten Muster und dem zweiten Muster zurückgegeben.Ihre
sed
Ausdruck ist ein Leerzeichen vor Ende, ich.e/^END/
. Sosed
bekommt die ab-Muster, aber nicht das Ende-Muster und hält den Druck bis zum Ende. Verwendensed '/^START=A/, /^END/!d' input_file
(Hinweis/^END/
)sed
regex, obwohl es macht die zitierte Ausgabe noch verwirrender (wie in 'ich kann nicht reproduzieren die zitierte Ausgabe mit dem original-Skript, aber fallen die überflüssige Leerzeichen und es funktioniert gut, wenn auch cackhanded'). Sie können zumindest die Vereinfachung der Letzte Teil Ihrerawk
Skript/END/{flag=0}
was könnte-flag auf null, wenn es war schon null, aber das schadet nicht. Sie können auch/START=A/,/END/{print}
die viel einfacher ist./START=A/,/END/{print}
dies ist viel einfacher, aber es ist schon in deiner Antwort 🙂 ich war nur Herumspielen mit einer fahne :). Tatsächlich, nach derawk
Lösung, die Sie gegeben haben, er braucht nicht, etwas anderes zu tun. Werde ich entfernen, meineawk
Lösung. Es könnte zu mehr Verwirrung führen als das zu tun jedem gut 😛