Ich denke, jeder kennt die nützlichen Linux cmd-Dienstprogramme head
und tail
. head
Ermöglicht das Drucken der ersten X-Zeilen einer Datei, tail
macht dasselbe, druckt jedoch das Ende der Datei. Was ist ein guter Befehl, um die Mitte einer Datei zu drucken? so etwas wie middle --start 10000000 --count 20
(drucke die 10'000'000. bis die 10'000'010. Zeile).
Ich bin auf der Suche nach etwas, das sich effizient mit großen Dateien befasst. Ich habe es versucht tail -n 10000000 | head 10
und es ist schrecklich langsam.
Antworten:
Möglicherweise können Sie dies ein wenig beschleunigen:
In diesen Befehlen
-n
bewirkt die Option, dasssed
das automatische Drucken des Musterbereichs unterdrückt wird. Derp
Befehl "print [s] the current pattern space" und derq
Befehl "Sofort das sed-Skript verlassen, ohne weitere Eingaben zu verarbeiten ..." Die Anführungszeichen stammen von dersed
man
Seite .Übrigens Ihr Befehl
beginnt in der zehnmillionsten Zeile ab dem Ende der Datei, während Ihr "mittlerer" Befehl anscheinend am zehnmillionsten vom Anfang beginnt, was äquivalent wäre zu:
Das Problem ist, dass bei unsortierten Dateien mit Zeilen variabler Länge jeder Prozess die Zeilenumbrüche durchlaufen muss. Es gibt keine Möglichkeit, das zu verkürzen.
Wenn die Datei jedoch sortiert ist (z. B. eine Protokolldatei mit Zeitstempeln) oder Zeilen mit fester Länge enthält, können Sie die Datei anhand einer Byte-Position durchsuchen. Im Beispiel für eine Protokolldatei können Sie eine Binärsuche für einen bestimmten Zeitraum durchführen, wie dies in meinem Python-Skript hier * der Fall ist. Bei der Datei mit fester Datensatzlänge ist das ganz einfach. Sie suchen nur nach
linelength * linecount
Zeichen in der Datei.* Ich habe weiterhin die Absicht, ein weiteres Update für dieses Skript zu veröffentlichen. Vielleicht komme ich eines Tages dazu.
quelle
sed
Version von Charles'middle
Funktion:middle() { local s=$1 c=$2; shift 2; sed -n "$s,$(($s + $c -1))p; $(($s + $c))q" "$@"; }
. Es werden mehrere Dateiargumente, Dateinamen mit Leerzeichen usw. verarbeitet. Mehrere Dateien werden zusammen verarbeitet, als wären sie auf die gleiche Weise wiesed
normalerweise cattiert worden (also würden sich mittlere 1000 100 Datei1 Datei2 über das Ende der ersten Datei bis zum Anfang erstrecken des zweiten, wenn der erste weniger als 1100 Zeilen hat).middle startline count filename
oder mehreren Dateinamen:middle startline count file1 file2 file3
oder mit Umleitung:middle startline count < filename
oder in einer Pipe:some_command |
mittlere Startzeilenzahl` odercat file* | middle startline count
Ich fand die folgende Verwendung von
sed
Hoffe, es ist nützlich für jemanden!
quelle
sed -n
Argument, die es gut lesbar macht.extract_lines(){sed -n "$1,+$2p" <file>}
die nach stdout schreibt.Dies ist mein erstes Mal hier! Wie auch immer, dieser ist einfach. Angenommen, Sie möchten die Zeile 8872 aus der Datei file.txt ziehen. So machen Sie es:
cat -n file.txt | grep '^ * 8872'
Jetzt geht es darum, danach 20 Zeilen zu finden. Um dies zu erreichen, tun Sie es
cat -n file.txt | grep -A 20 '^ * 8872'
Zeilen um oder davor finden Sie in den Flags -B und -C im grep-Handbuch.
quelle
cat -n file.txt | grep '^ *1'
Ergib alle Linien, die 1 auf ihrer rechten Seite haben. Wie wird Zeile 1 mit dieser Technik ausgegeben? Ich weiß ich kann -n 1 ... aber wie benutzt man grep?Die Antwort von Dennis ist der richtige Weg. Aber mit nur Kopf & Schwanz unter Bash:
Dies scannt die ersten $ 1 + $ 2 Zeilen zweimal und ist somit viel schlechter als Dennis 'Antwort. Aber Sie müssen sich nicht all diese sed Buchstaben merken, um es zu benutzen ...
quelle
$[...]
ist veraltet, zumindest in Bash. Außerdem fehlt ein Dateiparameter.middle 10 10 < /var/log/auth.log
.Verwenden Sie den folgenden Befehl, um den bestimmten Zeilenbereich abzurufen
Hier ist debug.log meine Datei, die aus einem Mangel an Zeilen besteht, und ich habe verwendet, um die Zeilen von 1220974 Zeilennummer bis 1513793 in eine Datei test.log zu drucken. Ich hoffe, es wird hilfreich sein, um den Zeilenbereich zu erfassen.
quelle
Eine rubinrote Oneliner-Version.
Es kann für jemanden nützlich sein. Die Lösungen mit "sed" von Dennis und Dox sind sehr schön, auch weil es schneller zu sein scheint.
quelle
Sie können 'nl' verwenden.
quelle
Zum Beispiel druckt diese awk Zeilen zwischen 20 und 40
quelle
Wenn Sie die Zeilennummern kennen, sagen Sie, Sie möchten die Zeilen 1, 3 und 5 aus einer Datei erhalten, sagen Sie / etc / passwd:
quelle
Perl ist König:
quelle