Lê a linha mais longa no arquivo usando while while loop?

1

Estive googling mas não consigo encontrar nenhum script que use o loop while para ler as linhas. Estou preso e não tenho certeza de onde começar

Aqui está a pergunta: Escreva um script bash longestline.sh que use um loop de leitura while para ler linhas de texto a partir de sua entrada padrão. o script deve acompanhar a linha mais longa que foi lida até o momento e, quando chegar ao final da entrada, imprimir essa linha.

Além disso, não tenho certeza se a pergunta me pede para inserir um arquivo com linhas de texto e ele irá lê-lo ou inserir as linhas de texto sozinho.

Obrigado KB

    
por Lagrange 13.02.2015 / 05:27

3 respostas

1

Como no link do cuonglm, loops em bash devem ser evitados.

Nesse espírito, o código abaixo obtém o comprimento da linha mais longa em um arquivo usando awk , uma ferramenta unix padrão, mas sem bash loops:

awk '{n=length($0)>n?length($0):n} END{print n}' file

Se você quiser imprimir a linha mais longa, em vez de obter seu tamanho, use:

awk '{longest=length($0)>length(longest)?$0:longest} END{print longest}' 
    
por 13.02.2015 / 06:12
0

Eu não tenho escrito bash em muito tempo, então eu vou aceitar qualquer tipo de crítica :) Minha solução seria algo assim:

n=0
longest=""
while read line; do
    len='echo $line | wc -m'
    if [ $len -ge $n ]; then
        n=$len
        longest=$line
    fi
done 

echo $longest

Eu li a sugestão de @ cuonglm, mas não consegui pensar em uma maneira de fazer isso usando menos invocações de processo. Estou aberto a sugestões, claro.

Em relação à sua última pergunta, isso realmente não importa. Esse script funcionaria com você inserindo as linhas ou com um arquivo sendo usado como entrada.

    
por 13.02.2015 / 05:53
0

Você pode obter uma lista de todos os números de linha, um por linha ordenada primeiro por comprimento e segundo por número de linha, começando por w / o maior como ...

</path/to/infile LC_ALL=C \
tr -c \n 1|grep -n '.\|'|sort -t: -rnk2

O método é muito simples - tr converte cada byte de entrada que não é um caractere de \n ewline para 1, grep -n preenche o número de cada linha e então : para todas as linhas em sua entrada, que sort , em seguida, ordena a ordem numérica inversa do campo 2cd até a parte final da linha, delimitada por : . Assim, a sequência mais longa de 1s flutua até o topo.

Você deve ficar atento, porém, se a entrada incluir caracteres multibyte, então isso será numerado apenas por byte - não por caractere. Fazer a última coisa de forma robusta não é um empreendimento menor (pelo que entendi) .

Em qualquer caso - em um local ASCII - o acima deve ser muito rápido mesmo para entradas muito grandes. E requer muito pouco mais para ser uma solução completa:

f=/path/to/file
n=$(<"$f" tr -c \n 1|grep -n '.\|'|sort -t: -rnk2|head -n1)
l=$(<"$f" head -n"${n%:*}"|tail -n1)
printf "Line #%s at #${#l} bytes. Its contents:\n%s\n" \
   "${n%:*} is (possibly tied-for) the longest in $f" "$l"
    
por 13.02.2015 / 11:48