¿Cómo obtener la línea más larga de un archivo?

10

Estoy interesado en averiguar el número de línea de la línea más larga de un archivo.

Por ejemplo, si tengo un archivo con el siguiente contenido:

lalala
tatatata
abracadabra
mu mu mu

¿Cómo puedo escribir un script bash que me dará un resultado como este 3 -> abracadabra:?

usuario214965
fuente

Respuestas:

9

No necesita un script para hacer esto. Un simple comando es suficiente:

egrep -n "^.{$(wc -L < filename)}$" filename

Esto funcionará incluso cuando tenga dos o más líneas con la misma longitud máxima.

Si desea que el resultado sea exactamente de esta forma:, 3 -> abracadabrause:

egrep -n "^.{$(wc -L < filename)}$" filename | sed 's/:/ -> /'

Referencias

Radu Rădeanu
fuente
3
@ don.joey: ese es el poder de unix. Comandos simples, que pueden trabajar juntos. aquí, busca "^. {n} $", es decir, cualquier línea que, entre el comienzo de la línea ( ^) y su final ( $) tenga exactamente n caracteres ( .{n}). Entonces solo necesita encontrar n: para esto usa un GNU-ism, "wc -L filename" (tenga en cuenta que esto no es posix) que devuelve la longitud de la línea más larga de nombre de archivo. Entonces él escoge cualquier línea que tenga la longitud más larga. $(cmd)se reemplaza por la salida de cmd.
Olivier Dulac
1
@OlivierDulac Gran comentario.
Radu Rădeanu
Aún mejor, también puede agregar (por ejemplo) -C 3a las opciones grep para obtener algunas líneas antes y después para el contexto
ShadSterling
8

Puede usar awkpara imprimir la longitud de cada línea ( length()) y el número de línea ( NR), luego invertir ( -r) sortel resultado por número ( -n):

$ awk '{ print length(), NR, $0 | "sort -rn" }' tmp.txt
10 3 abracadabr
8 4 mu mu mu
7 2 tatatat
6 1 lalala

Para mostrar solo la primera línea:

$ awk '{ print length(), NR, $0 | "sort -rn" }' tmp.txt | head -n 1
10 3 abracadabr
Atila O.
fuente
@ user214965, consulte mi actualización, el número de línea que se muestra es el segundo número en el resultado.
Atila O.
¿Qué pasa si hay 2 líneas con la misma longitud máxima?
Radu Rădeanu
@ RaduRădeanu buen punto. +1 para wc -L, no sabía sobre ese argumento. Es muy útil de hecho.
Atila O.
4

AO (N) se puede lograr con un perl one liner:

perl -e 'while (<>) { if (length > length $max) { $max=$_}}; print $max'

usos (donde machin es un nombre de archivo)

cat machin | perl -e 'while (<>) { if (length > length $max) { $max=$_}}; print $max'

o

perl -e 'while (<>) { if (length > length $max) { $max=$_}}; print $max' machin

o (menos claro pero más corto)

perl -ne 'if(length>length$m){$m=$_};END{print$m}' machin
MUY Bélgica
fuente
Mucho, mucho más eficiente. ¡Gracias! Lo estaba buscando.
test30
1
Funciona con archivos enormes +1
h3xStream
0

O (n) Para máquinas, por ejemplo OpenWRT, donde perl no está disponible, la versión @ awk @ podría ser útil.

awk 'length > l {l=length;line=$0} END {print line}' FILE

o pitón:

python -c "print max(open('$file', 'r'), key=len)"
test30
fuente
0

La respuesta de Radu es perfectamente suficiente y preferida, aunque si desea una solución más explícita y basada en shell, puede usar el siguiente script:

#!/bin/bash
longest_length=0
longest_string=0
while IFS= read -r line || [ -n "${line}"]
do
    if [ "${#line}" -gt "${longest_length}" ]
    then
        longest_length="${#line}"
        longest_string="$line"
    fi
done < "$1"

echo "${longest_string}"

Uso: ./find_longest.sh input.txt

Ejemplo:

$ cat input.txt                                                          
1 2 
2 3 a a a a
4 5 6 
1 1 1 5

$ ./find_longest.sh input.txt                                            
2 3 a a a a
Sergiy Kolodyazhnyy
fuente