Línea más larga en un archivo


198

Estoy buscando una manera simple de encontrar la longitud de la línea más larga en un archivo. Idealmente, sería un simple comando bash shell en lugar de un script.

Respuestas:


270

Usando wc (GNU coreutils) 7.4:

wc -L filename

da:

101 filename

56
Tenga en cuenta que solo las -c -l -m -wopciones son POSIX. -LEs un GNUismo.
Jens

44
Tenga en cuenta también que el resultado de -Ldepende de la configuración regional. ¡Algunos caracteres (tanto en el byte como en el sentido multibyte) pueden incluso no contarse en absoluto!
Walter Tross

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

12
OS X: usando homebrew, use gwc para GNU Word Count gwc -L filename
kaycoder

3
@xaxxon gwcestá en la coreutilsfórmula, que instala todos los coreutils de GNU con un gprefijo.
gsnedders

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

Como referencia: encontrar la línea más larga en un archivo


12
¿Por qué el comando extra cat? Simplemente proporcione el nombre del archivo directamente como argumento para awk.
Thomas Padron-McCarthy

18
@Thomas. Expresarlo como una tubería es más general que especificar un archivo como una opción. En mi caso, usaré la salida canalizada desde una consulta de base de datos.
Andrew Prock

1
esta es la mejor respuesta porque es más POSIX (bueno, funciona en OS X)
MK.

55
@MK. Sin embargo, este enfoque es O (n * log (n)) en el número de líneas, mientras que el enfoque de Ramon es O (n).
jub0bs

2
La clasificación de un archivo grande puede tardar horas en completarse y consumir gigabytes, incluso terabytes de espacio temporal, dependiendo del tamaño del archivo de entrada. Considere almacenar la longitud más larga y su registro asociado, luego imprímalo desde un END{}bloque.
Luv2code del

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

55
awk 'length>max{max=length}END{print max}' file
Chris Seymour

8
Esta respuesta proporciona el texto de la línea más larga del archivo en lugar de su longitud. Lo dejo como está, a pesar de que la pregunta pide la extensión porque sospecho que será útil para las personas que vienen a esta página simplemente mirando el título.
Ramon

3
Fácil de contar con WC.awk '{ if (length($0) > max) {max = length($0); maxline = $0} } END { print maxline }' YOURFILE | wc -c
Nick

1
¿Podría explicarnos cómo funciona esto?
Lnux

23

Solo por diversión y con fines educativos, la solución de shell POSIX pura , sin uso inútil de cat y sin bifurcación a comandos externos. Toma el nombre de archivo como primer argumento:

#!/bin/sh

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

66
no poder leer desde std in (a través de cat) en realidad reduce la utilidad de esto, no la mejora.
Andrew Prock

44
Bueno, el OP dijo explícitamente "archivo" y sin el < "$1"puede leer fácilmente desde stdin. Con una prueba $#incluso podría hacer ambas cosas, dependiendo de la cantidad de args. Simplemente no hay necesidad de gatos inútiles en este mundo. Los novatos deben ser enseñados en consecuencia desde el principio.
Jens

77
Esto debería tener una calificación más alta, es lo que solicitó el usuario. Agregue la función más larga () {MAX = 0 IFS = mientras lee -r línea; hacer si [$ {# line} -gt $ MAX]; entonces MAX = $ {# line}; fi done echo $ MAX} a tu .bashrc y puedes ejecutarlolongest < /usr/share/dict/words
skierpage

13
wc -L < filename

da

101

1
Gracias, he estado buscando una manera de evitar que wcel nombre de archivo
salga

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

Imprime la longitud, el número de línea y el contenido de la línea más larga.

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

Imprime una lista ordenada de todas las líneas, con números y longitudes de línea.

.es el operador de concatenación: se usa aquí después de length ()
$.es el número de línea actual
$_es la línea actual


Requiere ordenar un archivo ... el rendimiento sería terrible incluso para archivos de tamaño moderado y no funcionará para archivos más grandes. wc -LEs la mejor solución que vi hasta ahora.
Tagar

Usando un archivo de texto de 550,000 6,000,000 líneas como fuente (British National Corpus), la solución de perl tomó 12 segundos, mientras que wc -Ltomó 3 segundos
Chris Koknat

wc -Lsolo cuente los registros de números: esta Q estaba a punto de encontrar la línea más larga , no es exactamente lo mismo, por lo que esta no es una comparación precisa.
Tagar

6

Punto importante pasado por alto en los ejemplos anteriores.

Los siguientes 2 ejemplos cuentan pestañas expandidas

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

Los siguientes 2 cuentan pestañas no expandidas.

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

entonces

              Expanded    nonexpanded
$'nn\tnn'       10            5

5

Parece que todas las respuestas no dan el número de línea de la línea más larga. El siguiente comando puede dar el número de línea y la longitud aproximada:

$ 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

Aquí vamos. Eso encuentra mis comentarios odiosamente largos. Gracias amigo
Philip

Podría llevar esto un paso más allá y eliminar al gato. awk '{print length}' test.txt | sort -rn | head -1. Si también necesita el contenido real de la línea, entonces awk '{print length,$0}' test.txt | sort -k1 -rn| head -1
kakoma

3

En perl:

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

esto solo imprime la línea, no su longitud también.



2

Solo por diversión, aquí está la versión Powershell:

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

Y solo para obtener la longitud:

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

44
Entonces, ¿incluso los programadores de PowerShell deben usar gatos inútiles?
Jens

1
@Jens No estoy seguro de entenderte, cat en Powershell es solo un alias para Get-Content, cuyo comportamiento depende del contexto y el proveedor.
eddiegroves

¿Puede sorttomar filename.txt como argumento? Entonces el gato es inútil porque sort length filename.txt | select -last 1evita una tubería y un proceso que simplemente copia datos.
Jens

Como nota al margen, ¿qué es exactamente PowerShell? ¿Pensé que la utilidad powershell se usaba para máquinas Windows?
franklin

44
@Jens, los datos con frecuencia provienen de una secuencia en lugar de un nombre de archivo. Este es un lenguaje de herramientas estándar de Unix.
Andrew Prock

2

Estoy en un entorno Unix y trabajo con archivos comprimidos que tienen un tamaño de unos pocos GB. Probé los siguientes comandos usando un archivo comprimido de 2 GB con una longitud de registro de 2052.

  1. zcat <gzipped file> | wc -L

y

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

Los tiempos estaban en una avarage

  1. 117 segundos

  2. 109 segundos

Aquí está mi script después de aproximadamente 10 ejecuciones.

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"

No estoy seguro de que sea una comparación válida, me preocuparía que la awkversión se beneficie del almacenamiento en caché del bloque de disco de la wcversión que se está ejecutando primero (y genera la memoria caché del disco). Tendría que aleatorizar el orden de quién llama primero durante las diez carreras para que este argumento se mantenga.
Canonical Chris

1

Variación sobre el tema.

Este mostrará todas las líneas que tengan la longitud de la línea más larga encontrada en el archivo, conservando el orden en que aparecen en la fuente.

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

Entonces mi archivo

x
mn
xyz
123
abc

daré

xyz
123
abc

0

Si está utilizando MacOS y obtiene este error: wc: illegal option -- Lno necesita instalar GNU sipmly, haga esto.

Si todo lo que quiere hacer es obtener el recuento de los caracteres en la línea más larga del archivo y está utilizando OS X run:

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

Algo como esto;

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

Salidas:

The longest line in the file my_file has 117 characters

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.