Längste Zeile in einer Datei

197

Ich suche nach einer einfachen Möglichkeit, die Länge der längsten Zeile in einer Datei zu ermitteln. Im Idealfall handelt es sich um einen einfachen Bash-Shell-Befehl anstelle eines Skripts.

Andrew Prock
quelle

Antworten:

269

Verwenden von wc (GNU coreutils) 7.4:

wc -L filename

gibt:

101 filename
Daniel
quelle
56
Beachten Sie, dass nur die -c -l -m -wOptionen POSIX sind. -List ein GNUismus.
Jens
4
Beachten Sie auch, dass das Ergebnis von -Lvom Gebietsschema abhängt. Einige Zeichen (sowohl im Byte- als auch im Multibyte-Sinne) werden möglicherweise überhaupt nicht gezählt!
Walter Tross
7
OS X:wc: illegal option -- L usage: wc [-clmw] [file ...]
Hugo
12
OS X: Verwenden Sie Homebrew, verwenden Sie GWC für GNU Word Count GWC -L Dateiname
Kaycoder
3
@xaxxon gwcist in der coreutilsFormel enthalten, die alle GNU-Coreutils mit einem gPräfix installiert .
Gsnedders
100
awk '{print length, $0}' Input_file |sort -nr|head -1

Als Referenz: Suchen der längsten Zeile in einer Datei

Blass-blauer Punkt
quelle
12
Warum der zusätzliche Katzenbefehl? Geben Sie awk einfach den Dateinamen direkt als Argument.
Thomas Padron-McCarthy
18
@Thomas. Das Ausdrücken als Pipe ist allgemeiner als das Angeben einer Datei als Option. In meinem Fall verwende ich die Ausgabe einer Datenbankabfrage.
Andrew Prock
1
Dies ist die beste Antwort, weil es mehr POSIX ist (funktioniert unter OS X)
MK.
5
@MK. Dieser Ansatz ist jedoch O (n * log (n)) in der Anzahl der Zeilen, während Ramons Ansatz O (n) ist.
Jub0bs
2
Das Sortieren einer großen Datei kann Stunden dauern und Gigabyte oder sogar Terabyte temporären Speicherplatz verbrauchen, abhängig von der Größe der Eingabedatei. Speichern Sie die längste Länge und den zugehörigen Datensatz und drucken Sie sie dann aus einem END{}Block.
Luv2code
67
awk '{ if (length($0) > max) {max = length($0); maxline = $0} } END { print maxline }'  YOURFILE 
Ramon
quelle
3
awk '{ if (length($0) > max) max = length($0) } END { print max }' YOURFILE
Ke20
5
awk 'length>max{max=length}END{print max}' file
Chris Seymour
8
Diese Antwort gibt den Text der längsten Zeile in der Datei und nicht deren Länge an. Ich lasse es wie es ist, obwohl die Frage nach der Länge fragt, weil ich vermute, dass es für Leute nützlich sein wird, die auf diese Seite kommen und nur den Titel betrachten.
Ramon
3
Einfach, die Zählung mit WC zu erhalten ..awk '{ if (length($0) > max) {max = length($0); maxline = $0} } END { print maxline }' YOURFILE | wc -c
Nick
1
Würden Sie bitte erklären, wie das funktioniert?
Lnux
23

Nur zu Spaß- und Lernzwecken die reine POSIX-Shell-Lösung , ohne unnötigen Einsatz von Katze und ohne Verzicht auf externe Befehle. Nimmt den Dateinamen als erstes Argument:

#!/bin/sh

MAX=0 IFS=
while read -r line; do
  if [ ${#line} -gt $MAX ]; then MAX=${#line}; fi
done < "$1"
printf "$MAX\n"
Jens
quelle
6
Nicht in der Lage zu sein, von std in (über cat) zu lesen, verringert den Nutzen davon und verbessert ihn nicht.
Andrew Prock
4
Nun, das OP sagte explizit "Datei" und ohne das < "$1"kann es leicht von stdin lesen. Mit einem Test $#könnte es sogar beides tun, abhängig von der Anzahl der Argumente. Es gibt einfach keine Notwendigkeit für nutzlose Katzen auf dieser Welt. Neulinge sollten von Anfang an entsprechend unterrichtet werden.
Jens
7
Dies sollte höher bewertet werden, es ist das, wonach der Benutzer gefragt hat. Funktion am längsten hinzufügen () {MAX = 0 IFS = beim Lesen der Zeile -r; tun, wenn [$ {# line} -gt $ MAX]; dann MAX = $ {# line}; Wenn Sie fertig sind, geben Sie $ MAX} an Ihre .bashrc weiter und Sie könnenlongest < /usr/share/dict/words
skierpage
13
wc -L < filename

gibt

101
Anonym
quelle
1
Danke, ich habe nach einer Möglichkeit gesucht, die wcAusgabe des Dateinamens zu verhindern :)
Peter.O
11
perl -ne 'print length()."  line $.  $_"' myfile | sort -nr | head -n 1

Druckt die Länge, Zeilennummer und den Inhalt der längsten Zeile

perl -ne 'print length()."  line $.  $_"' myfile | sort -n

Druckt eine sortierte Liste aller Zeilen mit Zeilennummern und -längen

.ist der Verkettungsoperator - er wird hier verwendet, nachdem length ()
$.die aktuelle Zeilennummer
$_die aktuelle Zeile ist

Chris Koknat
quelle
Erfordert das Sortieren einer Datei. Die Leistung wäre selbst bei mittelgroßen Dateien schrecklich und funktioniert bei größeren Dateien nicht. wc -List die beste Lösung, die ich bisher gesehen habe.
Tagar
Unter Verwendung einer Textdatei mit 550.000 6.000.000 Zeilen als Quelle (British National Corpus) dauerte die Perl-Lösung 12 Sekunden, während sie wc -L3 Sekunden dauerte
Chris Koknat
wc -LZählen Sie einfach die Anzahl der Datensätze - dieses Q wollte gerade die längste Zeile finden - nicht ganz gleich, daher ist dies kein genauer Vergleich.
Tagar
6

Wichtiger übersehener Punkt in den obigen Beispielen.

Die folgenden 2 Beispiele zählen erweiterte Registerkarten

  wc -L  <"${SourceFile}" 
# or
  expand --tabs=8 "${SourceFile}" | awk '{ if (length($0) > max) {max = length($0)} } END { print max }'

Die folgenden 2 zählen nicht erweiterte Registerkarten.

  expand --tabs=1 "${SourceFile}" | wc -L 
# or
  awk '{ if (length($0) > max) {max = length($0)} } END { print max }' "${SourceFile}"

so

              Expanded    nonexpanded
$'nn\tnn'       10            5
John Kearney
quelle
5

Anscheinend gibt die Antwort nicht die Zeilennummer der längsten Zeile an. Der folgende Befehl kann die Zeilennummer und die ungefähre Länge angeben:

$ cat -n test.txt | awk '{print "longest_line_number: " $1 " length_with_line_number: " length}' | sort -k4 -nr | head -3
longest_line_number: 3 length_with_line_number: 13
longest_line_number: 4 length_with_line_number: 12
longest_line_number: 2 length_with_line_number: 11
Wangf
quelle
Na, bitte. Das findet meine widerlich langen Kommentare. Danke Alter.
Philip
Sie könnten noch einen Schritt weiter gehen und die Katze eliminieren. awk '{print length}' test.txt | sort -rn | head -1. Wenn Sie auch den eigentlichen Inhalt der Zeile benötigen, dann awk '{print length,$0}' test.txt | sort -k1 -rn| head -1
Kakoma
3

In Perl:

perl -ne 'print ($l = $_) if (length > length($l));' filename | tail -1

Dadurch wird nur die Linie gedruckt, nicht auch ihre Länge.

rsp
quelle
3

Hier sind Referenzen der Antwort

cat filename | awk '{print length, $0}'|sort -nr|head -1

http://wtanaka.com/node/7719

Nadir SOUALEM
quelle
1
Dieses zweite awk-Skript zeigt nur die längste Länge an, nicht die längste Zeile.
rsp
1
Komm schon ... Das sind die gleichen wie die ersten beiden Antworten, die mit den Referenzen hinzugefügt wurden.
Punkt
@rsp: Ich töte die zweite Antwort
Nadir SOUALEM
2

Nur zum Spaß, hier ist die Powershell-Version:

cat filename.txt | sort length | select -last 1

Und um nur die Länge zu bekommen:

(cat filename.txt | sort length | select -last 1).Length
eddiegroves
quelle
4
Also müssen selbst die Powershell-Programmierer nutzlose Katzen benutzen?
Jens
1
@Jens Ich bin mir nicht sicher, ob ich dich verstehe. Cat in Powershell ist nur ein Alias ​​für Get-Content, dessen Verhalten vom Kontext und vom Anbieter abhängt.
Eddiegroves
Kann sortfilename.txt als Argument verwendet werden? Dann ist die Katze nutzlos, weil sie sort length filename.txt | select -last 1eine Pipe und einen Prozess vermeidet, bei dem nur Daten kopiert werden.
Jens
Was genau ist Powershell als Nebenbemerkung? Ich dachte, das Powershell-Dienstprogramm wurde für Windows-Maschinen verwendet?
Franklin
4
@Jens, Daten stammen häufig aus einem Stream anstelle eines Dateinamens. Dies ist eine Standardsprache für Unix-Tools.
Andrew Prock
2

Ich bin in einer Unix-Umgebung und arbeite mit komprimierten Dateien, die einige GB groß sind. Ich habe die folgenden Befehle mit einer 2-GB-komprimierten Datei mit einer Datensatzlänge von 2052 getestet.

  1. zcat <gzipped file> | wc -L

und

  1. zcat <gzipped file> | awk '{print length}' | sort -u

Die Zeiten waren durchschnittlich

  1. 117 Sekunden

  2. 109 Sekunden

Hier ist mein Skript nach ca. 10 Läufen.

START=$(date +%s) ## time of start

zcat $1 |  wc -L

END=$(date +%s) ## time of end
DIFF=$(( $END - $START ))
echo "It took $DIFF seconds"

START=$(date +%s) ## time of start

zcat $1 |  awk '{print length}' | sort -u

END=$(date +%s) ## time of end
DIFF=$(( $END - $START ))
echo "It took $DIFF seconds"
Jon
quelle
Ich bin nicht sicher, ob dies ein gültiger Vergleich ist. Ich würde mir Sorgen machen, dass die awkVersion vom Zwischenspeichern der Festplattenblöcke der Version profitiert wc, die zuerst ausgeführt wird (und den Festplatten-Cache setzt). Sie müssten die Reihenfolge, wer in den zehn Läufen zuerst angerufen wird, nach dem Zufallsprinzip sortieren, damit dieses Argument erhalten bleibt.
Canonical Chris
1

Variation des Themas.

In diesem werden alle Zeilen mit der Länge der längsten in der Datei gefundenen Zeile angezeigt, wobei die Reihenfolge beibehalten wird, in der sie in der Quelle angezeigt werden.

FILE=myfile grep `tr -c "\n" "." < $FILE | sort | tail -1` $FILE

Also meine Datei

x
mn
xyz
123
abc

wird geben

xyz
123
abc
Martin Clayton
quelle
0

Wenn Sie MacOS verwenden und diesen Fehler erhalten: wc: illegal option -- LSie müssen GNU nicht einfach installieren.

Wenn Sie nur die Anzahl der Zeichen in der längsten Zeile der Datei abrufen möchten und OS X ausführen:

awk '{print length}' "$file_name" | sort -rn | head -1

Etwas wie das;

echo "The longest line in the file $file_name has $(awk '{print length}' "$file_name" | sort -rn | head -1) characters"

Ausgänge:

The longest line in the file my_file has 117 characters

Ivansito87
quelle