Bir dosyadan en uzun satırı nasıl alabilirim?


11

Bir dosyadan en uzun satırın satır numarasını öğrenmek istiyorum.

Örneğin, aşağıdaki içeriğe sahip bir dosyam varsa:

lalala
tatatata
abracadabra
mu mu mu

nasıl bana böyle bir çıkış şey verecek bir bash komut dosyası yazabilirsiniz: 3 -> abracadabra?

Yanıtlar:


10

Bunu yapmak için bir senaryoya ihtiyacınız yok. Basit bir komut yeterlidir:

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

Aynı maksimum uzunluğa sahip iki veya daha fazla hattınız olsa bile bu işe yarar.

Çıktının tam olarak bu biçimde olmasını istiyorsanız 3 -> abracadabra:

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

Referanslar:


3
@ don.joey: bu unix'in gücü. Birlikte çalışabilen basit komutlar. burada "^. {n} $" ifadesini, yani satırın başlangıcı ( ^) ile bitişi ( $) arasında tam olarak n karakter ( .{n}) olan herhangi bir satır arar . Daha sonra n'yi bulması gerekiyor: bunun için en uzun dosya adı satırının uzunluğunu döndüren bir GNU-ism, "wc -L dosya adı" (bunun posix olmadığını unutmayın) kullanıyor. Bu yüzden en uzun uzunluğa sahip herhangi bir çizgiyi açıyor. $(cmd)yerine cmd.
Olivier Dulac

1
@OlivierDulac Harika yorum.
Radu Rădeanu

Daha da iyisi, -C 3bağlam için önce ve sonra birkaç satır elde etmek için grep seçeneklerine (ör.) De ekleyebilirsiniz
ShadSterling

8

Sen kullanabilirsiniz awkher satırın (uzunluğunu yazdırmak için length()) ve satır numarası ( NR), sonra (ters -r) sort(sayısına sonucu -n):

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

Yalnızca ilk satırı göstermek için:

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

@ user214965 lütfen güncellememe bakın, görüntülenen satır numarası sonuçtaki ikinci sayıdır.
Attila O.

Aynı maksimum uzunluğa sahip 2 hat varsa ne olur?
Radu Rădeanu

@ RaduRădeanu iyi bir nokta. +1 için wc -L, bu argümanı bilmiyordum. Gerçekten çok faydalı.
Attila O.

4

AO (N) perl bir astar ile elde edilebilir:

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

kullanımları (burada makine bir dosya adıdır)

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

veya

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

veya (daha az net ancak daha kısa)

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

Çok, çok daha verimli. Teşekkürler! Onu arıyordum.
test30

1
Büyük dosyalarla +1 çalışır
h3xStream

0

O (n) Perl'in kullanılamadığı makineler için, örneğin OpenWRT, @ awk @ sürümü yararlı olabilir.

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

veya python:

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

0

Radu'nun cevabı mükemmel bir şekilde yeterlidir ve tercih edilir, ancak daha açık ve kabuk tabanlı bir çözüm istiyorsanız, aşağıdaki komut dosyasını kullanabilirsiniz:

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

Kullanımı: ./find_longest.sh input.txt

Misal:

$ 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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.