Самая длинная строка в файле

200

Я ищу простой способ найти длину самой длинной строки в файле. В идеале это будет простая команда оболочки bash вместо скрипта.

Эндрю Прок
источник

Ответы:

272

Использование wc (GNU coreutils) 7.4:

wc -L filename

дает:

101 filename
Даниил
источник
56
Обратите внимание, что только -c -l -m -wпараметры POSIX. -Lэто GNUism.
Дженс
4
Обратите внимание, что результат -Lзависит от локали. Некоторые символы (как в байтовом, так и в многобайтовом смысле) могут даже не учитываться вообще!
Уолтер Тросс
7
OS X:wc: illegal option -- L usage: wc [-clmw] [file ...]
Hugo
12
OS X: используя homebrew, используйте gwc для GNU Word Count gwc -L имя файла
kaycoder
3
@xaxxon gwcв coreutilsформуле, которая устанавливает все coreutils GNU с gпрефиксом.
gsnedders
101
awk '{print length, $0}' Input_file |sort -nr|head -1

Для справки: поиск самой длинной строки в файле

Бледно-голубая точка
источник
12
Почему дополнительная команда cat? Просто укажите имя файла в качестве аргумента для awk.
Томас Падрон-Маккарти
18
@Томас. Выражение его в виде канала является более общим, чем указание файла в качестве опции. В моем случае я буду использовать выходные данные из запроса к базе данных.
Эндрю Прок
1
это лучший ответ, потому что это больше POSIX (ну, работает на OS X)
МК.
5
@MK. Однако этот подход равен O (n * log (n)) по количеству строк, тогда как подход Рамона - O (n).
jub0bs
2
Сортировка большого файла может занять несколько часов и потреблять гигабайты, даже терабайты временного пространства в зависимости от размера входного файла. Подумайте о сохранении самой длинной длины и связанной с ней записи, а затем распечатайте ее из END{}блока.
Luv2code
67
awk '{ if (length($0) > max) {max = length($0); maxline = $0} } END { print maxline }'  YOURFILE 
Рамон
источник
3
awk '{ if (length($0) > max) max = length($0) } END { print max }' YOURFILE
ke20
5
awk 'length>max{max=length}END{print max}' file
Крис Сеймур
8
Этот ответ дает текст самой длинной строки в файле, а не ее длину. Я оставляю это как есть, хотя вопрос требует длины, потому что я подозреваю, что это будет полезно для людей, которые приходят на эту страницу, просто глядя на заголовок.
Рамон
3
Легко получить счет с помощью WC ..awk '{ if (length($0) > max) {max = length($0); maxline = $0} } END { print maxline }' YOURFILE | wc -c
Ник
1
Не могли бы вы объяснить, как это работает?
Lnux
23

Просто для забавы и в образовательных целях - чистое решение для оболочки POSIX , без бесполезного использования cat и без разветвлений для внешних команд. Принимает имя файла в качестве первого аргумента:

#!/bin/sh

MAX=0 IFS=
while read -r line; do
  if [ ${#line} -gt $MAX ]; then MAX=${#line}; fi
done < "$1"
printf "$MAX\n"
Jens
источник
6
неспособность читать с std в (через cat) фактически уменьшает полезность этого, а не увеличивает его.
Андрей Прок
4
Ну, ОП явно сказал "файл", и без < "$1"него его можно легко прочитать из стандартного ввода. С тестом на $#это можно было бы сделать и то и другое, в зависимости от количества аргументов. В этом мире просто нет нужды в бесполезных кошках. Новичков нужно учить соответственно с самого начала.
Дженс
7
Это должно быть оценено выше, это то, что просил пользователь. Добавьте функцию longest () {MAX = 0 IFS = при чтении строки -r; do if [$ {# line} -gt $ MAX]; затем MAX = $ {# line}; я сделал эхо $ MAX} для вашего .bashrc, и вы можете запуститьlongest < /usr/share/dict/words
skierpage 12.12.12
13
wc -L < filename

дает

101
анонимное
источник
1
Спасибо, я искал способ предотвратить wcвывод имени файла :)
Peter.O
11
perl -ne 'print length()."  line $.  $_"' myfile | sort -nr | head -n 1

Печать длины, номера строки и содержимого самой длинной строки

perl -ne 'print length()."  line $.  $_"' myfile | sort -n

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

.является оператором конкатенации - он используется здесь после того, как length ()
$.является текущим номером строки
$_ - текущая строка

Крис Кокнат
источник
Требуется сортировка файла .. производительность будет ужасной даже для файлов среднего размера и не будет работать для больших файлов. wc -Lлучшее решение, которое я видел до сих пор.
Тагар
Используя в качестве источника текстовый файл размером 6 000 000 550 МБ (British National Corpus), решение perl заняло 12 секунд, а wc -Lзаняло 3 секунды
Крис Кокнат,
wc -Lпросто посчитайте количество записей - этот Q собирался найти самую длинную строку - не совсем то же самое, так что это не точное сравнение.
Тагар
6

Важный упущенный момент в приведенных выше примерах.

Следующие 2 примера подсчитывают расширенные вкладки

  wc -L  <"${SourceFile}" 
# or
  expand --tabs=8 "${SourceFile}" | awk '{ if (length($0) > max) {max = length($0)} } END { print max }'

Следующие 2 считают не развернутые вкладки.

  expand --tabs=1 "${SourceFile}" | wc -L 
# or
  awk '{ if (length($0) > max) {max = length($0)} } END { print max }' "${SourceFile}"

так

              Expanded    nonexpanded
$'nn\tnn'       10            5
Джон Кирни
источник
5

Похоже, все ответы не дают номер строки самой длинной строки. Следующая команда может дать номер строки и приблизительную длину:

$ cat -n test.txt | awk '{print "longest_line_number: " $1 " length_with_line_number: " length}' | sort -k4 -nr | head -3
longest_line_number: 3 length_with_line_number: 13
longest_line_number: 4 length_with_line_number: 12
longest_line_number: 2 length_with_line_number: 11
wangf
источник
Там мы идем. Это находит мои неприятно длинные комментарии. Спасибо приятель.
Филипп
Вы могли бы сделать этот шаг дальше и устранить кошку. awk '{print length}' test.txt | sort -rn | head -1, Если вам тоже нужен фактический контент строки awk '{print length,$0}' test.txt | sort -k1 -rn| head -1
kakoma
3

В perl:

perl -ne 'print ($l = $_) if (length > length($l));' filename | tail -1

это только печатает линию, а не ее длину тоже.

RSP
источник
3

Вот ссылки на ответ

cat filename | awk '{print length, $0}'|sort -nr|head -1

http://wtanaka.com/node/7719

Надир СУАЛЕМ
источник
1
Этот второй скрипт awk покажет вам только самую длинную длину, а не покажет самую длинную строку.
rsp
1
Да ладно .. Это так же, как первые два ответа, добавленные со ссылками.
Бледно-голубая точка
@rsp: я убиваю второго ответчика
Nadir SOUALEM
2

Просто для удовольствия, вот версия Powershell:

cat filename.txt | sort length | select -last 1

И просто получить длину:

(cat filename.txt | sort length | select -last 1).Length
eddiegroves
источник
4
Так что даже программисты PowerShell должны использовать бесполезных кошек?
Дженс
1
@Jens Не уверен, что я вас понимаю, cat в Powershell - это просто псевдоним для Get-Content, поведение которого зависит от контекста и провайдера.
Eddiegroves
Может sortвзять filename.txt в качестве аргумента? Тогда кошка бесполезна, потому что sort length filename.txt | select -last 1избегает канала и процесса, который просто копирует данные.
Дженс
Как sidenote, что именно PowerShell? Я думал, что утилита powershell использовалась для Windows-машин?
Франклин
4
@Jens, данные часто приходят из потока вместо имени файла. Это стандартная идиома инструментов Unix.
Андрей Прок
2

Я работаю в среде Unix и работаю с сжатыми файлами размером в несколько ГБ. Я протестировал следующие команды, используя сжатый файл размером 2 ГБ с длиной записи 2052.

  1. zcat <gzipped file> | wc -L

и

  1. zcat <gzipped file> | awk '{print length}' | sort -u

Время было в среднем

  1. 117 секунд

  2. 109 секунд

Вот мой сценарий после 10 пробежек.

START=$(date +%s) ## time of start

zcat $1 |  wc -L

END=$(date +%s) ## time of end
DIFF=$(( $END - $START ))
echo "It took $DIFF seconds"

START=$(date +%s) ## time of start

zcat $1 |  awk '{print length}' | sort -u

END=$(date +%s) ## time of end
DIFF=$(( $END - $START ))
echo "It took $DIFF seconds"
Джон
источник
Я не уверен, что это правильное сравнение, я бы беспокоился, что awkверсия выигрывает от кеширования дискового блока той wcверсии, которая запускается первой (и заполняет кэш диска). Вам нужно было бы рандомизировать порядок вызова первыми за десять прогонов, чтобы этот аргумент оставался неизменным.
Канонический Крис
1

Вариация на тему.

Эта строка покажет все строки, имеющие длину самой длинной строки в файле, сохраняя порядок, в котором они отображаются в источнике.

FILE=myfile grep `tr -c "\n" "." < $FILE | sort | tail -1` $FILE

Итак, мой файл

x
mn
xyz
123
abc

дам

xyz
123
abc
Мартин Клейтон
источник
0

Если вы используете MacOS и получаете эту ошибку: wc: illegal option -- Lвам не нужно устанавливать GNU sipmly, сделайте это.

Если все, что вы хотите сделать, это просто получить количество символов в самой длинной строке файла, и вы используете OS X, запустите:

awk '{print length}' "$file_name" | sort -rn | head -1

Что-то вроде этого;

echo "The longest line in the file $file_name has $(awk '{print length}' "$file_name" | sort -rn | head -1) characters"

Выходы:

The longest line in the file my_file has 117 characters

Ivansito87
источник