Come ottenere la linea più lunga da un file?


10

Sono interessato a scoprire il numero di riga della riga più lunga da un file.

Ad esempio, se ho un file con il seguente contenuto:

lalala
tatatata
abracadabra
mu mu mu

come posso scrivere uno script bash che mi darà un risultato simile a questo 3 -> abracadabra:?

Risposte:


9

Non hai bisogno di una sceneggiatura per farlo. È sufficiente un semplice comando:

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

Funzionerà anche quando hai due o più linee con la stessa lunghezza massima.

Se vuoi che l'output sia esattamente in questo formato:, 3 -> abracadabraallora usa:

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

Riferimenti:


3
@ don.joey: questo è il potere di unix. Comandi semplici, che possono lavorare insieme. qui, cerca "^. {n} $", ovvero qualsiasi riga che, tra l'inizio di line ( ^) e la sua fine ( $) ha esattamente n caratteri ( .{n}). Quindi deve solo trovare n: per questo usa un GNU-ism, "wc -L nomefile" (nota che questo non è posix) che restituisce la lunghezza della linea più lunga del nome file. Quindi insegue qualsiasi linea che abbia la lunghezza più lunga. $(cmd)è sostituito dall'output di cmd.
Olivier Dulac,

1
@OlivierDulac Ottimo commento.
Radu Rădeanu,

Ancora meglio, puoi anche aggiungere (ad esempio) -C 3alle opzioni grep per ottenere alcune righe prima e dopo il contesto
ShadSterling

8

È possibile utilizzare awkper stampare la lunghezza di ciascuna riga ( length()) e il numero di riga ( NR), quindi invertire ( -r) sortil risultato in base al numero ( -n):

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

Per mostrare solo la prima riga:

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

@utente214965, vedere il mio aggiornamento, il numero di riga visualizzato è il secondo numero nel risultato.
Attila O.,

Cosa succede se ci sono 2 linee con la stessa lunghezza massima?
Radu Rădeanu,

@ RaduRădeanu buon punto. +1 per wc -L, non sapevo di quell'argomento. È davvero molto utile.
Attila O.,

4

AO (N) può essere ottenuto con un rivestimento perl uno:

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

usi (dove machin è un nome file)

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 (meno chiaro ma più breve)

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

Molto, molto più efficiente. Grazie! Lo stavo cercando.
test30

1
Funziona con file di grandi dimensioni +1
h3xStream

0

O (n) Per le macchine, ad esempio OpenWRT, dove perl non è disponibile, la versione @ awk @ potrebbe essere utile.

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

o pitone:

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

0

La risposta di Radu è perfettamente sufficiente e preferita, anche se se si desidera una soluzione più esplicita e basata su shell, è possibile utilizzare il seguente 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

Esempio:

$ 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
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.