Comment obtenir la ligne la plus longue d'un fichier?


10

Je souhaite connaître le numéro de ligne de la plus longue ligne d'un fichier.

Par exemple, si j'ai un fichier avec le contenu suivant:

lalala
tatatata
abracadabra
mu mu mu

comment puis-je écrire un script bash qui me donnera une sortie quelque chose comme ceci 3 -> abracadabra:?

Réponses:


9

Vous n'avez pas besoin d'un script pour cela. Une simple commande suffit:

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

Cela fonctionnera même lorsque vous avez deux lignes ou plus avec la même longueur maximale.

Si vous voulez que la sortie soit exactement sous cette forme:, 3 -> abracadabraalors utilisez:

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

Références:


3
@ don.joey: c'est le pouvoir d'Unix. Des commandes simples, qui peuvent fonctionner ensemble. ici, il cherche "^. {n} $", c'est-à-dire toute ligne qui, entre le début de la ligne ( ^) et sa fin ( $) a exactement n caractères ( .{n}). Ensuite, il a juste besoin de trouver n: pour cela, il utilise un GNU-isme, "wc -L filename" (notez que ce n'est pas posix) qui retourne la longueur de la plus longue ligne de nom de fichier. Donc, il attrape n'importe quelle ligne qui a la plus longue longueur. $(cmd)est remplacé par la sortie de cmd.
Olivier Dulac

1
@OlivierDulac Excellent commentaire.
Radu Rădeanu

Encore mieux, vous pouvez également ajouter (par exemple) -C 3aux options grep pour obtenir quelques lignes avant et après pour le contexte
ShadSterling

8

Vous pouvez utiliser awkpour imprimer la longueur de chaque ligne ( length()) et le numéro de ligne ( NR), puis inverser ( -r) sortle résultat par numéro ( -n):

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

Pour afficher uniquement la première ligne:

$ awk '{ print length(), NR, $0 | "sort -rn" }' tmp.txt | head -n 1
10 3 abracadabr

@ user214965 veuillez voir ma mise à jour, le numéro de ligne affiché est le deuxième numéro du résultat.
Attila O.

Et s'il y a 2 lignes avec la même longueur maximale?
Radu Rădeanu

@ RaduRădeanu bon point. +1 pour wc -L, je ne connaissais pas cet argument. C'est très utile en effet.
Attila O.

4

L'AO (N) peut être obtenu avec un revêtement perl one:

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

utilisations (où machin est un nom de fichier)

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

ou

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

ou (moins clair mais plus court)

perl -ne 'if(length>length$m){$m=$_};END{print$m}' machin

Beaucoup, beaucoup plus efficace. Merci! Je le cherchais.
test30

1
Fonctionne avec des fichiers énormes +1
h3xStream

0

O (n) Pour les machines, par exemple OpenWRT, où perl n'est pas disponible, @ awk @ version peut être utile.

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

ou python:

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

0

La réponse de Radu est parfaitement suffisante et préférée, bien que si vous voulez une solution plus explicite et basée sur le shell, vous pouvez utiliser le script suivant:

#!/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}"

Usage: ./find_longest.sh input.txt

Exemple:

$ 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
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.