it-swarm.com.de

Wie werden bestimmte Zeilen aus einer Textdatei unter Linux angezeigt?

Ich denke, jeder kennt die nützlichen Linux-Dienstprogramme für cmd-Zeilen head und tail. Mit head können Sie die ersten X-Zeilen einer Datei drucken. tail macht dasselbe, druckt jedoch das Ende der Datei. Was ist ein guter Befehl, um die Mitte einer Datei zu drucken? etwas wie middle --start 10000000 --count 20 (Drucken Sie die Zeilen 10'000'000 bis 10'000'010).

Ich suche etwas, das große Dateien effizient verarbeitet. Ich habe es versucht tail -n 10000000 | head 10 und es ist schrecklich langsam.

92
Boaz
sed -n '10000000,10000020p' filename

Möglicherweise können Sie dies ein wenig beschleunigen:

sed -n '10000000,10000020p; 10000021q' filename

In diesen Befehlen ist die Option -n bewirkt, dass sed "das automatische Drucken des Musterraums unterdrückt". Der Befehl p "druckt den aktuellen Musterraum aus" und der Befehl q "Beenden Sie das sed-Skript sofort, ohne weitere Eingaben zu verarbeiten ..." Die Anführungszeichen stammen aus dem sedman Seite .

Übrigens dein Befehl

tail -n 10000000 filename | head 10

beginnt in der zehnmillionsten Zeile vom Ende der Datei, während Ihr "mittlerer" Befehl an der zehnmillionsten Zeile vom Anfang zu beginnen scheint gleichwertig sein mit:

head -n 10000010 filename | tail 10

Das Problem ist, dass für unsortierte Dateien mit Zeilen variabler Länge jeder Prozess die Datei durchlaufen muss, die Zeilenumbrüche zählt. 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 aufweist, können Sie die Datei anhand einer Byteposition suchen. Im Beispiel für eine Protokolldatei können Sie eine binäre Suche für eine Reihe von Malen durchführen, wie dies bei my Python script hier * der Fall ist. Im Fall der Datei mit fester Datensatzlänge , es ist wirklich einfach. Sie suchen nur linelength * linecount Zeichen in die Datei.

* Ich habe weiterhin die Absicht, ein weiteres Update für dieses Skript zu veröffentlichen. Vielleicht komme ich eines Tages dazu.

Ich fand die folgende Verwendung von sed heraus

sed -n '10000000,+20p'  filename

Hoffe, es ist nützlich für jemanden!

29
Dox

Dies ist mein erstes Mal hier! Wie auch immer, dieser ist einfach. Angenommen, Sie möchten die Zeile 8872 aus Ihrer Datei file.txt ziehen. So geht's:

cat -n file.txt | grep '^ * 8872'

Nun ist die Frage, 20 Zeilen danach zu finden. Um dies zu erreichen, tun Sie dies

cat -n file.txt | grep -A 20 '^ * 8872'

Für Linien um oder vor siehe die Flags -B und -C im grep-Handbuch.

4
Dennis

Verwenden Sie den folgenden Befehl, um den bestimmten Zeilenbereich abzurufen

awk 'NR < 1220974{next}1;NR==1513793{exit}' debug.log | tee -a test.log

Hier ist debug.log meine Datei, die aus einem Mangel an Zeilen besteht, und ich habe die Zeilen von 1220974 Zeilennummer bis 1513793 in eine Datei test.log gedruckt. Ich hoffe, es ist hilfreich für die Erfassung des Linienbereichs.

1
newbie13

Dennis 'sed Antwort ist der richtige Weg. Aber mit nur Kopf & Schwanz unter Bash:

 middle () {head -n $ [$ 1 + $ 2] | Schwanz -n $ 2; } 

Dies scannt die ersten $ 1 + $ 2 Zeilen zweimal, ist also viel schlimmer als Dennis 'Antwort. Aber Sie müssen sich nicht an all diese sed Buchstaben erinnern, um es zu benutzen ...

1
Charles Stewart

A Ruby Oneliner-Version.

Ruby -pe 'next unless $. > 10000000 && $. < 10000020' < filename.txt

Es kann für jemanden nützlich sein. Die Lösungen mit 'sed' von Dennis und Dox sind sehr schön, auch weil sie schneller zu sein scheinen.

0
shardan

Perl ist König:

Perl -ne 'print if ($. == 10000000 .. $. == 10000020)' filename
0
Peter V. Mørch

Wenn Sie die Zeilennummern kennen, sagen Sie, Sie möchten die Zeilen 1, 3 und 5 aus einer Datei abrufen, sagen Sie/etc/passwd:

Perl -e 'while(<>){if(++$l~~[1,3,5]){print}}' < /etc/passwd
0
Dagelf

Sie können 'nl' verwenden.

nl filename | grep <line_num>
0
Ajay

Zum Beispiel druckt diese awk Zeilen zwischen 20 und 40

awk '{if ((NR> 20) && (NR <40)) print $ 0}'/etc/passwd

0
Hrvoje Špoljar