Ich habe einen SQL-Speicherauszug mit ~ 23000 Zeilen, der Daten im Wert von mehreren Datenbanken enthält. Ich muss einen bestimmten Abschnitt dieser Datei (dh die Daten für eine einzelne Datenbank) extrahieren und in eine neue Datei einfügen. Ich kenne sowohl die Start- als auch die Endzeilennummer der gewünschten Daten.
Kennt jemand einen Unix-Befehl (oder eine Reihe von Befehlen), um alle Zeilen aus einer Datei zwischen den Zeilen 16224 und 16482 zu extrahieren und sie dann in eine neue Datei umzuleiten?
unix
command-line
sed
text-processing
Adam J. Forster
quelle
quelle
Antworten:
Aus dem sed-Handbuch :
und
quelle
sed -n '16224,16482p;16483q' filename
. Andernfalls wird sed bis zum Ende weiter scannen (oder zumindest meine Version).Wobei 16224,16482 die Startzeilennummer und die Endzeilennummer einschließlich sind. Dies ist 1-indiziert.
-n
Unterdrückt das Echo der Eingabe als Ausgabe, was Sie eindeutig nicht möchten. Die Zahlen geben den Zeilenbereich an, mit dem der folgende Befehl ausgeführt werden soll. Der Befehlp
druckt die entsprechenden Zeilen aus.quelle
sed -n '16224,16482p;16482q' orig-data-file > new-file
.Ganz einfach mit Kopf / Schwanz:
mit sed:
mit awk:
quelle
tail
.sed -n 16224,16482p' in.sql >out.sql
awk 'NR>=16224&&NR<=16482' in.sql > out.sql
head -16482 in.sql | tail -$((16482-16224)) >out.sql
die Berechnung auf bashtail -n +16224
, um die Berechnung zu reduzierenSie könnten 'vi' und dann den folgenden Befehl verwenden:
Alternative:
BEARBEITEN: - Nur um eine Erklärung hinzuzufügen, verwenden Sie head -n 16482 , um die ersten 16482 Zeilen anzuzeigen, und verwenden Sie tail -n 258 , um die letzten 258 Zeilen aus der ersten Ausgabe herauszuholen.
quelle
cat
Befehl nicht;head
kann eine Datei direkt lesen. Dies ist langsamer als bei vielen Alternativen, da 2 (3 wie gezeigt) Befehle verwendet werden, wobei 1 ausreicht.cat
). Andere Lösungen benötigen mindestens einige Minuten. Auch die schnellste Variante von GNU scheint zu seintail -n +XXX filename | head XXX
.Es gibt einen anderen Ansatz mit
awk
:Wenn die Datei sehr groß ist, kann es gut sein,
exit
nach dem Lesen der letzten gewünschten Zeile. Auf diese Weise werden die folgenden Zeilen nicht unnötig gelesen:quelle
print; exit
. Vielen Dank !awk 'NR==16224, NR==16482; NR==16482 {exit}' file
quelle
quelle
sollte den Trick machen. Der Nachteil dieses Ansatzes ist, dass Sie die Arithmetik ausführen müssen, um das Argument für tail zu bestimmen und zu berücksichtigen, ob das 'zwischen' die Endzeile enthalten soll oder nicht.
quelle
cat
Befehl nicht;head
kann eine Datei direkt lesen. Dies ist langsamer als bei vielen Alternativen, da 2 (3 wie gezeigt) Befehle verwendet werden, wobei 1 ausreicht.| tail -$((16482 - 16224))
.Ich stehe auf den Schultern von Boxxar und mag Folgendes:
z.B
Das
$
bedeutet "letzte Zeile", alsosed
druckt der erste Befehl alle Zeilen beginnend mit der Zeile16224
und der zweite Befehlsed
beendet nach dem Drucken der Zeile16428
. (Das Hinzufügen1
desq
Bereichs in der Lösung von boxxar scheint nicht erforderlich zu sein.)Ich mag diese Variante, weil ich die Endzeilennummer nicht zweimal angeben muss. Und ich habe gemessen, dass die Verwendung
$
keine nachteiligen Auswirkungen auf die Leistung hat.quelle
sed -n '16224,16482p' < dump.sql
quelle
Schnell und dreckig:
Wahrscheinlich nicht der beste Weg, aber es sollte funktionieren.
Übrigens: 259 = 16482-16224 + 1.
quelle
Ich habe ein Haskell-Programm namens Splitter geschrieben , das genau dies tut: Lesen Sie meinen Release-Blog-Beitrag durch .
Sie können das Programm wie folgt verwenden:
Und das ist alles, was dazu gehört. Sie benötigen Haskell, um es zu installieren. Gerade:
Und du bist fertig. Ich hoffe, dass Sie dieses Programm nützlich finden.
quelle
splitter
nur von der Standardeingabe? In gewissem Sinne spielt es keine Rolle; Dercat
Befehl ist überflüssig, ob er es tut oder nicht. Verwenden Sie entwedersplitter 16224-16482 < somefile
oder (wenn Dateinamenargumente erforderlich sind)splitter 16224-16482 somefile
.Sogar wir können dies tun, um in der Befehlszeile zu überprüfen:
Zum Beispiel:
quelle
cat
In beiden Fällen benötigen Sie den Befehl nicht.sed
ist perfekt in der Lage, Dateien selbst zu lesen, oder Sie können Standardeingaben aus einer Datei umleiten.Mit Rubin:
quelle
Ich wollte gerade den Kopf / Schwanz-Trick posten, aber eigentlich würde ich wahrscheinlich nur Emacs starten. ;-);
Öffnen Sie die neue Ausgabedatei und speichern Sie sie mit ctl-y
Lassen Sie mich sehen, was passiert.
quelle
Ich würde ... benutzen:
FNR enthält die Datensatznummer der Zeile, die aus der Datei gelesen wird.
quelle
Ich wollte dasselbe mit einem Skript unter Verwendung einer Variablen tun und erreichte dies, indem ich die $ -Variable in Anführungszeichen setzte, um den Variablennamen vom p zu trennen:
Ich wollte eine Liste in separate Ordner aufteilen und fand die erste Frage und beantwortete einen nützlichen Schritt. (Split-Befehl ist keine Option auf dem alten Betriebssystem, auf das ich den Code portieren muss).
quelle
Ich habe ein kleines Bash-Skript geschrieben, das Sie über Ihre Befehlszeile ausführen können, solange Sie Ihren PATH so aktualisieren, dass er sein Verzeichnis enthält (oder Sie können ihn in einem Verzeichnis ablegen, das bereits im PATH enthalten ist).
Verwendung: $ pinch Dateiname Startzeile Endzeile
quelle
wc
Befehls, der die Festplattenbandbreite verschwendet, insbesondere bei Gigabyte-Dateien. In vielerlei Hinsicht ist dies gut dokumentiert, aber es ist auch ein technischer Overkill.Dies könnte für Sie funktionieren (GNU sed):
oder Bash ausnutzen:
quelle
Verwenden von ed:
-s
unterdrückt die Diagnoseausgabe; Die eigentlichen Befehle befinden sich in einer Here-Zeichenfolge. Führt insbesondere16224,16482p
denp
Befehl (Drucken) im gewünschten Zeilenadressbereich aus.quelle
Das -n in den Antworten akzeptieren funktioniert. Hier ist ein anderer Weg, falls Sie dazu neigen.
Dies bewirkt Folgendes:
quelle
cat file | sed
ist besser geschrieben alssed file
Da es sich um das Extrahieren von Textzeilen aus einer Textdatei handelt, werde ich einen Sonderfall angeben, in dem Sie alle Zeilen extrahieren möchten, die einem bestimmten Muster entsprechen.
Druckt die Zeile [Daten] und die verbleibenden Zeilen. Wenn Sie den Text von Zeile 1 bis zum Muster haben möchten, geben Sie Folgendes ein: sed -n '1, / Data / p' myfile. Wenn Sie zwei Muster kennen (besser in Ihrem Text eindeutig sein), können sowohl die Anfangs- als auch die Endzeile des Bereichs mit Übereinstimmungen angegeben werden.
quelle