Найдовший рядок у файлі


200

Я шукаю простий спосіб знайти довжину найдовшого рядка у файлі. В ідеалі це була б проста команда bash shell замість сценарію.

Відповіді:


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 ...]
Уго

12
OS X: використовуючи homebrew, використовуйте gwc для GNU Word Count gwc -L ім'я файлу
kaycoder

3
@xaxxon gwcє у coreutilsформулі, яка встановлює всі основні програми GNU з gпрефіксом.
gsnedders

100
awk '{print length, $0}' Input_file |sort -nr|head -1

Для довідки: Пошук найдовшого рядка у файлі


12
Чому додаткова команда кішки? Просто наведіть ім'я файлу безпосередньо як аргумент для пробудження.
Томас Падрон-Маккарті

18
@Thomas. Вираження цього як труба є більш загальним, ніж визначення файлу як опції. У моєму випадку я буду використовувати вихідний запит із запиту бази даних.
Ендрю Прок

1
ця найкраща відповідь, тому що це більше POSIX (ну, працює на OS X)
MK.

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
Скажіть, будь ласка, пояснення того, як це працює?
Лнукс

23

Тільки для розваги та навчальних цілей, чисте рішення оболонки POSIX , без марного використання кота та без прив’язки до зовнішніх команд. Приймає ім'я файлу як перший аргумент:

#!/bin/sh

MAX=0 IFS=
while read -r line; do
  if [ ${#line} -gt $MAX ]; then MAX=${#line}; fi
done < "$1"
printf "$MAX\n"

6
неможливість читати з std в (через cat) фактично знижує корисність цього, а не підвищує його.
Ендрю Прок

4
Ну, в ОП чітко сказано "файл" і без цього < "$1"його можна легко прочитати з stdin. З тестом для $#цього навіть могли обійтися, залежно від кількості арг. Просто в цьому світі немає потреби в непотрібних котів. Новачок слід навчати відповідно з самого початку.
Єнс

7
Це слід оцінювати вище, саме це запитував користувач. Додайте функцію найдовше () {MAX = 0 IFS = під час читання -r рядка; робити, якщо [$ {# рядок} -gt $ MAX]; тоді MAX = $ {# рядок}; фі зробили відлуння $ MAX} на свій .bashrc і ви можете запуститиlongest < /usr/share/dict/words
skierpage


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

Друкує довжину, номер рядка та вміст найдовшого рядка

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

Друкує відсортований список усіх рядків із номерами рядків та довжинами

.є оператором конкатенації - він використовується тут після length ()
$.- номер поточного рядка
$_- поточний рядок


Потрібна сортування файлу. Продуктивність буде жахливою навіть для файлів середнього розміру і не працюватиме для великих файлів. wc -Lнайкраще рішення, яке я бачив досі.
Тагар

Використовуючи текстовий файл 550 000 МБ в якості джерела (Британський національний корпус), рішення 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

Там ми йдемо. Це знаходить мої неприємно довгі коментарі. Дякую, чувак.
Філіп

Ви можете зробити цей крок далі і усунути кішку. awk '{print length}' test.txt | sort -rn | head -1. Якщо вам також потрібен власний вміст рядка, awk '{print length,$0}' test.txt | sort -k1 -rn| head -1
власний

3

У перл:

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

це друкує лише рядок, а не її довжину.


3

Ось довідники візитника

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

http://wtanaka.com/node/7719


1
Цей другий сценарій awk покаже лише найдовшу довжину, а не покаже найдовший рядок.
rsp

1
Давай..Це такі ж, як перші два відповіді, додані з посиланнями.
Блідо-блакитна крапка

@rsp: я вбиваю другого вражаника
Надір СОУАЛЕМ

2

Просто для задоволення, ось версія Powershell:

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

А щоб просто отримати довжину:

(cat filename.txt | sort length | select -last 1).Length

4
Тож навіть програмісти в оболонці повинні використовувати марних котів?
Єнс

1
@Jens Не впевнений, що я вас розумію, кішка в Powershell - це лише псевдонім Get-Content, поведінка якого залежить від контексту та постачальника.
eddiegroves

Чи можна sortвзяти filename.txt як аргумент? Тоді кішка марна, оскільки sort length filename.txt | select -last 1уникає труби і процесу, який просто копіює дані навколо.
Єнс

Як сторонне позначення, що саме таке патрон? Я думав, що утиліта powerhell використовується для віконних машин?
франклін

4
@Jens, дані часто надходять із потоку замість імені файлу. Це стандартна ідіома інструментів Unix.
Ендрю Прок

2

Я перебуваю в середовищі Unix і працюю з gzipped файлами розміром у кілька ГБ. Я перевірив наступні команди, використовуючи gzipped файл 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 run:

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

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