Як отримати найдовший рядок з файлу?


10

Мені цікаво дізнатись номер рядка найдовшого рядка з файлу.

Наприклад, якщо у мене є файл із таким вмістом:

lalala
tatatata
abracadabra
mu mu mu

як я можу написати скрипт bash, який дасть мені вихід щось подібне 3 -> abracadabra:?

Відповіді:


9

Для цього вам не потрібен сценарій. Досить простої команди:

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

Це працюватиме навіть тоді, коли у вас є дві або більше ліній з однаковою максимальною довжиною.

Якщо ви хочете, щоб результат був точно в такому вигляді:, 3 -> abracadabraтоді використовуйте:

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

Список літератури:


3
@ don.joey: це сила Unix. Прості команди, які можуть працювати разом. тут він шукає "^. {n} $", тобто будь-який рядок, який між початком рядка ( ^) і його кінцем ( $) має рівно n символів ( .{n}). Тоді йому просто потрібно знайти n: для цього він використовує GNU-ism, "wc -L ім'я файлу" (зауважте, що це не posix), який повертає довжину найдовшого рядка імені файлу. Таким чином він стискає будь-яку лінію, яка має найбільшу довжину. $(cmd)замінюється на вихід cmd.
Олів'є Дулак

1
@OlivierDulac Чудовий коментар.
Radu Rădeanu

Ще краще, ви також можете додати (наприклад) -C 3до опцій grep, щоб отримати кілька рядків до та після контексту
ShadSterling

8

Ви можете використовувати awkдля друку довжини кожного рядка ( length()) та номера рядка ( NR), а потім обернути ( -r) sortрезультат на число ( -n):

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

Щоб показати лише перший рядок:

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

@ user214965, будь ласка, дивіться моє оновлення, номер рядка, що відображається, є другим номером в результаті.
Аттіла О.

Що робити, якщо є 2 лінії з однаковою максимальною довжиною?
Radu Rădeanu

@ RaduRădeanu хороший момент. +1 для wc -L, я не знав про цей аргумент. Це дійсно дуже корисно.
Аттіла О.

4

AO (N) може бути досягнуто за допомогою вкладиші perl one:

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

США (де machin - це ім'я файлу)

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

або

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

або (менш чіткий, але коротший)

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

Багато, набагато ефективніше. Дякую! Шукав його.
тест30

1
Працює з величезними файлами +1
h3xStream

0

O (n) Для машин, наприклад OpenWRT, де perl недоступний, версія @ awk @ може бути корисною.

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

або пітон:

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

0

Відповідь Раду цілком достатня і бажана, хоча якщо ви хочете більш чіткого і на основі оболонки рішення, то ви можете використовувати наступний сценарій:

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

Використання: ./find_longest.sh input.txt

Приклад:

$ 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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.