Riga più lunga in un file


198

Sto cercando un modo semplice per trovare la lunghezza della linea più lunga in un file. Idealmente, sarebbe un semplice comando bash shell invece di uno script.

Risposte:


270

Usando wc (GNU coreutils) 7.4:

wc -L filename

dà:

101 filename

56
Nota che solo le -c -l -m -wopzioni sono POSIX. -Lè un GNUismo.
Jens,

4
Si noti inoltre che il risultato di -Ldipende dalle impostazioni internazionali. Alcuni caratteri (sia nel byte che nel senso multibyte) potrebbero addirittura non essere contati affatto!
Walter Tross,

7
OS X:wc: illegal option -- L usage: wc [-clmw] [file ...]
Hugo,

12
OS X: usando homebrew, usa gwc per GNU Conteggio parole gwc -L nomefile
kaycoder

3
@xaxxon gwcè nella coreutilsformula, che installa tutti i coreutils GNU con un gprefisso.
gsnedders,

100
awk '{print length, $0}' Input_file |sort -nr|head -1

Per riferimento: ricerca della riga più lunga in un file


12
Perché il comando extra cat? Basta dare il nome del file direttamente come argomento per awk.
Thomas Padron-McCarthy,

18
@Tommaso. Esprimerlo come pipe è più generale che specificare un file come opzione. Nel mio caso, userò l'output reindirizzato da una query del database.
Andrew Prock,

1
questa è la risposta migliore perché è più POSIX (beh, funziona su OS X)
MK.

5
@MK. Tuttavia, questo approccio è O (n * log (n)) nel numero di righe, mentre l'approccio di Ramon è O (n).
jub0bs,

2
L'ordinamento di un file di grandi dimensioni può richiedere ore per completare e consumare gigabyte, anche terabyte di spazio temporaneo a seconda delle dimensioni del file di input. Considera di memorizzare la lunghezza più lunga e il record associato, quindi stampalo da un END{}blocco.
Luv2code,

67
awk '{ if (length($0) > max) {max = length($0); maxline = $0} } END { print maxline }'  YOURFILE 

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
Questa risposta fornisce il testo della riga più lunga nel file anziché la sua lunghezza. Lo sto lasciando così com'è anche se la domanda richiede una certa lunghezza perché sospetto che sarà utile per le persone che arrivano in questa pagina solo guardando il titolo.
Ramon,

3
Facile ottenere il conteggio usando WC ..awk '{ if (length($0) > max) {max = length($0); maxline = $0} } END { print maxline }' YOURFILE | wc -c
Nick,

1
Potresti spiegare per favore come funziona?
Lnux,

23

Solo per scopi educativi e divertenti, la pura soluzione shell POSIX , senza l'uso inutile di cat e nessun passaggio a comandi esterni. Prende il nome file come primo argomento:

#!/bin/sh

MAX=0 IFS=
while read -r line; do
  if [ ${#line} -gt $MAX ]; then MAX=${#line}; fi
done < "$1"
printf "$MAX\n"

6
non essere in grado di leggere da std in (tramite cat) in realtà riduce l'utilità di questo, non lo migliora.
Andrew Prock,

4
Bene, l'OP ha esplicitamente detto "file" e senza di < "$1"esso può facilmente leggere da stdin. Con un test per $#esso potrebbe anche fare entrambe le cose, a seconda del numero di argomenti. Non c'è bisogno di gatti inutili in questo mondo. I neofiti dovrebbero essere insegnati di conseguenza fin dall'inizio.
Jens,

7
Questo dovrebbe essere valutato più in alto, è quello che l'utente ha chiesto. Aggiungi funzione longest () {MAX = 0 IFS = mentre leggi -r riga; fare se [$ {# line} -gt $ MAX]; quindi MAX = $ {# line}; fi done echo $ MAX} sul tuo .bashrc e puoi correrelongest < /usr/share/dict/words
skierpage il

13
wc -L < filename

101

1
Grazie, sono stato alla ricerca di un modo per impedire l' wcoutput del nome file :)
Peter.O

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

Stampa la lunghezza, il numero di riga e il contenuto della riga più lunga

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

Stampa un elenco ordinato di tutte le righe, con numeri di riga e lunghezze

.è l'operatore di concatenazione - viene utilizzato qui dopo length ()
$.è il numero di riga corrente
$_è la riga corrente


Richiede l'ordinamento di un file .. le prestazioni sarebbero terribili anche per file di dimensioni moderate e non funzionerebbero per file di dimensioni maggiori. wc -Lè la migliore soluzione che ho visto finora.
Tagar,

Utilizzando un file di testo di 6.000.000 di righe da 550 MB come sorgente (British National Corpus), la soluzione perl impiegò 12 secondi, mentre wc -Limpiegarono 3 secondi
Chris Koknat,

wc -Lconta solo i record numerici - questa Q stava per trovare la riga più lunga - non è esattamente la stessa, quindi questo non è un confronto accurato.
Tagar

6

Importante punto trascurato negli esempi precedenti.

I seguenti 2 esempi contano le schede espanse

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

I seguenti 2 contano le schede non estese.

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

così

              Expanded    nonexpanded
$'nn\tnn'       10            5

5

Sembra che tutta la risposta non dia il numero di riga della linea più lunga. Il seguente comando può fornire il numero di riga e la lunghezza approssimativa:

$ 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

Eccoci. Questo trova i miei commenti odiosamente lunghi. Grazie amico.
Filippo,

Potresti fare un ulteriore passo avanti ed eliminare il gatto. awk '{print length}' test.txt | sort -rn | head -1. Se hai bisogno anche del contenuto della linea attuale, allora 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

questo stampa solo la linea, non anche la sua lunghezza.



2

Solo per divertimento, ecco la versione di Powershell:

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

E per ottenere solo la lunghezza:

(cat filename.txt | sort length | select -last 1).Length

4
Quindi anche i programmatori PowerShell devono usare gatti inutili?
Jens,

1
@Jens Non sono sicuro di averti capito, cat in Powershell è solo un alias per Get-Content, il cui comportamento dipende dal contesto e dal provider.
eddiegroves il

Può sortprendere nomefile.txt come argomento? Quindi il gatto è inutile perché sort length filename.txt | select -last 1evita una pipe e un processo che copia semplicemente i dati.
Jens,

Come sidenote cos'è esattamente PowerShell? Pensavo che l'utility PowerShell fosse usata per macchine Windows?
Franklin,

4
@Jens, i dati provengono spesso da uno stream anziché da un nome file. Questo è un linguaggio standard di strumenti unix.
Andrew Prock,

2

Sono in un ambiente Unix e lavoro con file compressi con dimensioni di pochi GB. Ho testato i seguenti comandi usando un file gzipped da 2 GB con lunghezza record di 2052.

  1. zcat <gzipped file> | wc -L

e

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

I tempi erano in media

  1. 117 secondi

  2. 109 secondi

Ecco la mia sceneggiatura dopo circa 10 prove.

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"

Non sono sicuro che si tratti di un confronto valido, sarei preoccupato che la awkversione benefici della memorizzazione nella cache del blocco disco della wcversione che è in esecuzione per prima (e semina la cache del disco). Dovresti randomizzare l'ordine di chi viene chiamato per primo nelle dieci esecuzioni per far sì che questo argomento rimanga.
Canonical Chris,

1

Variazione sul tema.

Questo mostrerà tutte le linee che hanno la lunghezza della linea più lunga trovata nel file, mantenendo l'ordine in cui appaiono nella fonte.

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

Quindi miofile

x
mn
xyz
123
abc

darà

xyz
123
abc

0

Se stai usando MacOS e ricevi questo errore: wc: illegal option -- L riscontrando non è necessario installare GNU sipmly farlo.

Se tutto ciò che vuoi fare è ottenere il conteggio dei caratteri nella riga più lunga del file e stai utilizzando OS X Run:

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

Qualcosa come questo;

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

Uscite:

The longest line in the file my_file has 117 characters

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.