Как печатать самую длинную строку в файле?

Я ищу простейший метод для печати самой длинной строки в файле. Я сделал какой-то поисковик и неожиданно не мог найти ответа. Я часто печатаю длину самой длинной строки в файле, но я не знаю, как на самом деле печатать самую длинную строку. Может ли кто-нибудь предоставить решение для печати самой длинной строки в файле? Заранее спасибо.

9 Solutions collect form web for “Как печатать самую длинную строку в файле?”

cat ./text | awk ' { if ( length > x ) { x = length; y = $0 } }END{ print y }' 

UPD : обобщая все рекомендации в комментариях

 awk 'length > max_length { max_length = length; longest_line = $0 } END { print longest_line }' ./text 
 sed -rn "/.{$(<file expand -t1 |wc -L)}/{p;q}" file 

Сначала он считывает файл внутри подстановки команд и выводит длину самой длинной строки (ранее, expand вкладки в пробелы, чтобы преодолеть семантику wc -L – каждая вкладка в строке добавит 8 вместо 1 в строку длина). Эта длина затем используется в выражении sed означающем «найти строку длиной этого количества символов, напечатать ее, а затем выйти». Таким образом, это фактически может быть оптимальным, так как самая длинная строка находится рядом с верхней частью файла, heheh (спасибо за потрясающие и конструктивные комментарии).

Другой, я думал раньше, чем sed (в bash):

 #!/bin/bash while read -r line; do (( ${#line} > max )) && max=${#line} && longest="$line" done echo "$longest" 

Вот решение Perl:

 perl -e 'while(<>){ $l=length; $l>$m && do {$c=$_; $m=$l} } print $c' file.txt 

Или, если вы хотите напечатать все самые длинные строки

 perl -e 'while(<>){ $l=length; push @{$k{$l}},$_; $m=$l if $l>$m; } print @{$k{$m}}' file.txt 

Поскольку мне нечего было делать, я провел несколько тестов в текстовом файле 625M. Удивительно, но мое решение Perl было последовательно быстрее других. Разумеется, разница с принятым решением awk крошечная, но она есть. Очевидно, что решения, которые печатают несколько строк, медленнее, поэтому я отсортировал их по типу, быстрее всего до самых медленных.

Печать только одной из самых длинных строк:

 $ time perl -e 'while(<>){ $l=length; $l>$m && do {$c=$_; $m=$l} } print $c' file.txt real 0m3.837s user 0m3.724s sys 0m0.096s $ time awk 'length > max_length { max_length = length; longest_line = $0 } END { print longest_line }' file.txt real 0m5.835s user 0m5.604s sys 0m0.204s $ time sed -rn "/.{$(<file.txt expand -t1 |wc -L)}/{p;q}" file.txt real 2m37.348s user 2m39.990s sys 0m1.868s 

Распечатайте самые длинные строки:

 $ time perl -e 'while(<>){ $l=length; push @{$k{$l}},$_; $m=$l if $l>$m; } print @{$k{$m}}' file.txt real 0m9.263s user 0m8.417s sys 0m0.760s $ time awk 'length >x { delete y; x=length } length==x { y[NR]=$0 } END{ for (z in y) print y[z] }' file.txt real 0m10.220s user 0m9.925s sys 0m0.252s ## This is Chris Down's bash solution $ time ./a.sh < file.txt Max line length: 254 Lines matched with that length: 2 real 8m36.975s user 8m17.495s sys 0m17.153s 

В чистом bash:

 #!/bin/bash _max_length=0 while IFS= read -r _line; do _length="${#_line}" if (( _length > _max_length )); then _max_length=${_length} _max_line=( "${_line}" ) elif (( _length == _max_length )); then _max_line+=( "${_line}" ) fi done printf 'Max line length: %d\n' "${_max_length}" printf 'Lines matched with that length: %d\n' "${#_max_line[@]}" (( ${#_max_line[@]} )) && printf '%s\n' '----------------' "${_max_line[@]}" 

Следующий пример должен был быть, и должен был быть комментарием к ответу dmitry.malikov , но из-за бесполезного использования видимого пространства комментариев там я решил представить его здесь, где он, по крайней мере, будет замечен. ..

Это простая вариация однопроходного awk-метода dmitry.
Он печатает все «одинаковые длинные» строки. (Примечание: delete array – это расширение gawk).

 awk 'length >x { delete y; x=length } length==x { y[NR]=$0 } END{ for (z in y) print y[z] }' file 

Греп – первая самая длинная линия

 grep -Em1 "^.{$(wc -L <file.txt)}\$" file.txt 

Команда необычно трудно читать без практики, потому что она смешивает синтаксис shell и regexp.
Для объяснения я сначала использую упрощенный псевдокод. Строки, начинающиеся с ## , не запускаются в оболочке.
В этом упрощенном коде используется имя файла F и исключается цитирование и части регулярных выражений для удобства чтения.

Как это работает

Команда состоит из двух частей: grep – и wc invocation:

## grep "^.{$( wc -LF )}$" F

wc используется в расширении процесса, $( ... ) , поэтому он запускается до grep . Он вычисляет длину самой длинной линии. Синтаксис расширения оболочки смешивается с синтаксисом шаблона регулярного выражения в запутанном виде, поэтому я буду разлагать расширение процесса:

## wc -LF
42
## grep "^.{42}$" F

Здесь расширение процесса было заменено значением, которое оно вернет, создавая используемую grep строку grep . Теперь мы можем легко прочитать регулярное выражение: оно точно совпадает с началом ( ^ ) до конца ( $ ) строки. Выражение между ними соответствует любому символу, кроме символа новой строки, повторяется в 42 раза. Комбинированные, это строки, состоящие из ровно 42 символов.

Теперь вернемся к действительным командам оболочки. Параметр grep -E ( --extended-regexp ) позволяет избежать функции {} для удобочитаемости. Параметр -m 1 ( --max-count=1 ) останавливает работу после того, как найдена первая строка. Команда < в команде wc записывает файл в свой stdin, чтобы wc печатал имя файла вместе с длиной.

Какие самые длинные линии?

Чтобы сделать примеры более удобочитаемыми с именами файлов, происходящими дважды, я буду использовать переменную f для имени файла; Каждый $f в этом примере может быть заменен именем файла.

 f="file.txt" 

Покажите первую длинную строку – первую строку, которая длиннее самой длинной строки:

 grep -E -m1 "^.{$(wc -L <"$f")}\$" "$f" 

Показать все самые длинные строки – все строки длиной до самой длинной строки:

 grep -E "^.{$(wc -L <"$f")}\$" "$f" 

Покажите последнюю длинную строку – последнюю строку, длина которой длиннее:

 tac "$f" | grep -E -m1 "^.{$(wc -L <"$f")}\$" 

Покажите единственную длинную строку – длинную строку длиннее всех других строк или не удалось:

 [ $(grep -E "^.{$(wc -L <"$f")}\$" "$f" | wc -l) = 1 ] && grep -E "^.{$(wc -L <"$f")}\$" "$f" 

(Последняя команда еще более неэффективна, чем остальные, поскольку она повторяет полную команду grep. Очевидно, она должна быть разложена так, чтобы выходные данные wc и строк, написанные grep , сохранялись в переменных.
Обратите внимание, что все самые длинные строки могут фактически быть всеми строками. Для сохранения в переменной необходимо сохранить только первые две строки.)

Для этого я разработал небольшой сценарий оболочки. Он отображает длину, строку # и линию по длине, которая превышает определенный размер, например 80 символов:

 #!/bin/sh # Author: Surinder if test $# -lt 2 then echo "usage: $0 length file1 file2 ..." echo "usage: $0 80 hello.c" exit 1 fi length=$1 shift LONGLINE=/tmp/longest-line-$$.awk cat << EOF > $LONGLINE BEGIN { } /.*/ { current_length=length(\$0); if (current_length >= expected_length) { printf("%d at line # %d %s\n", current_length, NR, \$0); } } END { } EOF for file in $* do echo "$file" cat $file | awk -v expected_length=$length -f $LONGLINE |sort -nr done rm $LONGLINE 

https://github.com/lordofrain/tools/blob/master/longest-line/longest-line.sh

 cat filename | awk '{ print length }' | sort -n | tail -1 

Вы можете использовать wc :

 wc -L fileName 
  • Текст между двумя тегами
  • awk попарные разности
  • как получить данные из результата grep?
  • awk - упростить этот скрипт
  • Избавиться от десятичного разряда и отменить запятую
  • Выровнять шестнадцатеричный текстовый файл по 9 байт каждой строки
  • grep: Как найти консоль для закрытия?
  • Сопоставление двух разных линий, расположенных по крайней мере на N прямых друг от друга
  • вставить строку для отсутствующего значения
  • awk: emulate 'pr -mt file *'
  • Перечислите дни рождения в том порядке, в котором они придут с сегодняшнего дня
  • Linux и Unix - лучшая ОС в мире.