2013-04-02 21 views
11

Ich habe einige große CSV-Dateien, wo ich alle Daten zwischen Zeile X, die Muster "x" und Linie Y, die Muster enthält "y"Sed/Awk - ziehe Linien zwischen Muster x und y

zum Beispiel:

other_data 
Header 
data 
data 
data 
Footer 
other_data 

ich Rohr alles in der Lage sein zwischen (einschließlich) Kopf -> Footer in eine neue Datei.

Danke!

Antwort

16

Mit awk es ist ziemlich einfach:

awk '/Header/ { show=1 } show; /Footer/ { show=0 }' 

Grundsätzlich Zustand halten in einer Variablen namens show. Wenn wir die Kopfzeile drücken, schalten wir sie ein, Footer schalten wir aus. Während es aktiviert ist, führt die show Regel die Standardaktion zum Drucken des Datensatzes aus.

+0

, die perfekt funktioniert, danke für die Erklärung! – Numpty

+3

+1 da dies die richtige Antwort ist, da es leicht verbessert werden kann, um Situationen abzudecken, in denen Sie die erste Zeile oder die letzte Zeile oder beide Zeilen oder etwas anderes, was Sie tun möchten, drucken wollen. Die Lösungen unter Verwendung von/start /,/end/Bereiche, während leicht kürzer fallen auseinander bei den geringsten Anforderungen ändern - das Muster macht Lösungen für triviale Probleme etwas kürzer, aber Lösungen für nicht-triviale Probleme viel länger und komplexer oder erfordern ein Umschreiben zu dieser Stil. –

14

Es ist ziemlich einfach in sed:

sed -n '/Header/,/Footer/p' 

oder

sed '/Header/,/Footer/!d' 
+0

Funktioniert genauso gut wie AWK, danke. Ich werde Fatal das Akzeptierte geben, da er zuerst hier war, aber danke dafür. Hier ist ein +1 – Numpty

+1

Ich fand die erste Option (das '/ p 'Ende) 1/4 der Zeit als die awk Lösung zu nehmen. Die zweite Option ('/! D') benötigte die gleiche Zeit wie awk. In einer großen Datei beginnt es zu zählen. – RaveTheTadpole

+0

Dies funktioniert auch, wenn der Begrenzer derselbe ist. Die awk-Version funktioniert nur, wenn sie anders sind. – akostadinov

9

Ein anderer Weg, mit awk:

awk '/Header/,/Footer/' file 
Header 
data 
data 
data 
Footer 

Gerade die Ausgabe umleiten in einem newfile zu speichern:

awk '/Header/,/Footer/' file > newfile 
+1

Dein ist das schönste, also bekommst du einen Punkt :) – Numpty

+0

Ja, das sieht nach dem Besten aus. +1. – Beta

+0

Ich bin gespannt: Gibt es ein "von Header bis zum Ende der Datei" mit dieser Art von Muster? (Es ist sehr einfach mit der Top-Awk-Lösung, aber ich frage mich, ob es einen "Ende der Datei" Marker statt "/ Footer /") –

1

Dies könnte für Sie (GNU sed) arbeiten:

sed '/^Header/,/^Footer/w new_file' file 
+0

Dies funktioniert, sondern auch die gesamte Datei auf stdout umgeleitet. Dies macht es auch schwierig, mit Rohren zu verwenden. – Sparhawk

Verwandte Themen