676 Stimmen

Wie kann ich einen bestimmten Bereich von Zeilen aus einer Textdatei unter Unix extrahieren?

Ich habe einen SQL-Dump mit ~23000 Zeilen, der Daten aus mehreren Datenbanken enthält. Ich muss einen bestimmten Abschnitt dieser Datei (d. h. die Daten für eine einzelne Datenbank) extrahieren und in eine neue Datei einfügen. Ich kenne sowohl die Anfangs- 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 z.B. Zeile 16224 und 16482 zu extrahieren und sie dann in eine neue Datei umzuleiten?

5voto

rami Punkte 1586

sed -n '16224,16482p' < dump.sql

3voto

Carl Blakeley Punkte 31

Ruby verwenden:

ruby -ne 'puts "#{$.}: #{$_}" if $. >= 32613500 && $. <= 32614500' < GND.rdf > GND.extract.rdf

3voto

Ich habe gerade die 3 oben genannten Lösungen verglichen, die für mich funktionieren:

  • awk
  • sed
  • "Kopf+Schwanz"

Der Dank für die 3 Lösungen geht an:

  • @boxxar
  • @avandeursen
  • @wds
  • @manveru
  • @sibaz
  • @SOFe
  • @fedorqui 'SO hört auf zu schaden'
  • @Robin A. Meade

Ich verwende eine große Datei, die ich auf meinem Server finde:

# wc fo2debug.1.log
   10421186    19448208 38795491134 fo2debug.1.log

38 Gb in 10,4 Millionen Leitungen.

Und ja, ich habe ein Logrotate-Problem : ))


Machen Sie Ihre Einsätze!


Ermittelt 256 Zeilen vom Anfang der Datei.

# time sed -n '1001,1256p;1256q' fo2debug.1.log | wc -l
256

real    0m0,003s
user    0m0,000s
sys     0m0,004s

# time head -1256 fo2debug.1.log | tail -n +1001 | wc -l
256

real    0m0,003s
user    0m0,006s
sys     0m0,000s

# time awk 'NR==1001, NR==1256; NR==1256 {exit}' fo2debug.1.log | wc -l
256

real    0m0,002s
user    0m0,004s
sys     0m0,000s

Awk gewonnen. Technischer Gleichstand auf dem zweiten Platz zwischen sed und "head+tail".


256 Zeilen am Ende des ersten Drittels der Datei erhalten.

# time sed -n '3473001,3473256p;3473256q' fo2debug.1.log | wc -l
256

real    0m0,265s
user    0m0,242s
sys     0m0,024s

# time head -3473256 fo2debug.1.log | tail -n +3473001 | wc -l
256

real    0m0,308s
user    0m0,313s
sys     0m0,145s

# time awk 'NR==3473001, NR==3473256; NR==3473256 {exit}' fo2debug.1.log | wc -l
256

real    0m0,393s
user    0m0,326s
sys     0m0,068s

Sed gewonnen. Gefolgt von "head+tail" und schließlich von awk.


256 Zeilen am Ende des zweiten Drittels der Datei erhalten.

# time sed -n '6947001,6947256p;6947256q' fo2debug.1.log | wc -l
A256

real    0m0,525s
user    0m0,462s
sys     0m0,064s

# time head -6947256 fo2debug.1.log | tail -n +6947001 | wc -l
256

real    0m0,615s
user    0m0,488s
sys     0m0,423s

# time awk 'NR==6947001, NR==6947256; NR==6947256 {exit}' fo2debug.1.log | wc -l
256

real    0m0,779s
user    0m0,650s
sys     0m0,130s

Gleiche Ergebnisse.

Sed gewonnen. Gefolgt von "head+tail" und schließlich von awk.


Sie erhalten 256 Zeilen am Ende der Datei.

# time sed -n '10420001,10420256p;10420256q' fo2debug.1.log | wc -l
256

real    1m50,017s
user    0m12,735s
sys     0m22,926s

# time head -10420256 fo2debug.1.log | tail -n +10420001 | wc -l
256

real    1m48,269s
user    0m42,404s
sys     0m51,015s

# time awk 'NR==10420001, NR==10420256; NR==10420256 {exit}' fo2debug.1.log | wc -l
256

real    1m49,106s
user    0m12,322s
sys     0m18,576s

Und plötzlich: eine Wendung!

"Kopf+Schwanz" gewonnen. Gefolgt von awk und schließlich sed.


(einige Stunden später...)

Tut mir leid, Leute!

Meine obige Analyse ist ein Beispiel für einen grundlegenden Fehler bei der Durchführung einer Analyse.

Die Schwachstelle besteht darin, dass die für die Analyse verwendeten Mittel nicht genau bekannt sind.

In diesem Fall habe ich eine Protokolldatei verwendet, um die Leistung einer Suche nach einer bestimmten Anzahl von Zeilen darin zu analysieren.

Mit drei verschiedenen Techniken wurde an verschiedenen Stellen in der Datei gesucht, wobei die Leistung der Techniken an jeder Stelle verglichen und geprüft wurde, ob die Ergebnisse je nach Stelle in der Datei, an der die Suche durchgeführt wurde, variierten.

Mein Fehler war, dass ich von einer gewissen Homogenität des Inhalts der Protokolldatei ausging.

In der Praxis treten lange Zeilen häufiger am Ende der Datei auf.

Daher kann die offensichtliche Schlussfolgerung, dass längere Suchvorgänge (näher am Ende der Datei) mit einer bestimmten Technik besser sind, verzerrt sein. In der Tat kann diese Technik besser sein, wenn es um längere Zeilen geht. Das muss noch bestätigt werden.

3voto

KevinY Punkte 1119

Ich wollte dasselbe von einem Skript aus tun, das eine Variable verwendet, und erreichte es, indem ich Anführungszeichen um die Variable $variable setzte, um den Variablennamen vom p zu trennen:

sed -n "$first","$count"p imagelist.txt >"$imageblock"

Ich wollte eine Liste in einzelne Ordner aufteilen und fand die anfängliche Frage und Antwort einen nützlichen Schritt. (Der Split-Befehl ist auf dem alten Betriebssystem, auf das ich den Code portieren muss, nicht möglich).

3voto

Chinmoy Padhi Punkte 39

Auch wir können dies in der Kommandozeile überprüfen:

cat filename|sed 'n1,n2!d' > abc.txt

Zum Beispiel:

cat foo.pl|sed '100,200!d' > abc.txt

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X