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

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

26 голосов | спросил dr.bunsen 13 72011vEurope/Moscow11bEurope/MoscowSun, 13 Nov 2011 04:58:47 +0400 2011, 04:58:47

9 ответов


29
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 
ответил ДМИТРИЙ МАЛИКОВ 13 72011vEurope/Moscow11bEurope/MoscowSun, 13 Nov 2011 05:02:11 +0400 2011, 05:02:11
5
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"
ответил ata 13 72011vEurope/Moscow11bEurope/MoscowSun, 13 Nov 2011 06:22:03 +0400 2011, 06:22:03
3

Вот решение 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
ответил terdon 1 Maypm13 2013, 23:28:17
2

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

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

awk 'length >x { delete y; x=length }
     length==x { y[NR]=$0 } END{ for (z in y) print y[z] }' file
ответил Peter.O 14 12011vEurope/Moscow11bEurope/MoscowMon, 14 Nov 2011 08:16:23 +0400 2011, 08:16:23
2

Grep первая самая длинная строка

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

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

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

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

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

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

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

Здесь расширение процесса было заменено значением, которое оно вернет, создав используемую командную строку 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, сохраняются в переменных.
Обратите внимание, что все самые длинные строки могут фактически быть всеми строками. Для сохранения в переменной необходимо сохранить только первые две строки.)

ответил Volker Siegel 10 12014vEurope/Moscow11bEurope/MoscowMon, 10 Nov 2014 02:37:21 +0300 2014, 02:37:21
1

В чистом 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[@]}"
ответил Chris Down 14 12011vEurope/Moscow11bEurope/MoscowMon, 14 Nov 2011 00:09:54 +0400 2011, 00:09:54
1
cat filename | awk '{ print length }' | sort -n | tail -1
ответил aspinalln 24 thEurope/Moscowp30Europe/Moscow09bEurope/MoscowTue, 24 Sep 2013 14:30:50 +0400 2013, 14:30:50
0

Я разработал для этого небольшой сценарий оболочки. Он отображает длину, строку # и линию по длине, которая превышает определенный размер, например 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/инструменты /блоб /ведущий /длинная линия /longest-line.sh

ответил Surinder432 19 +03002016-10-19T09:53:17+03:00312016bEurope/MoscowWed, 19 Oct 2016 09:53:17 +0300 2016, 09:53:17
-3

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

wc -L fileName
ответил ynot1074 1 Maypm13 2013, 15:37:00

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132