Список файлов, отсортированных по количеству строк, которые они содержат

32

Как я могу перечислить количество строк в файлах /group/book/four/word, отсортированных по количеству строк, которые они содержат?

ls -l команда выводит их список, но не сортирует их

Кен Р
источник
1
Вы хотите, чтобы файлы перечислялись числом строк, или указывали количество строк в файлах или оба? ls -lне дает количество строк. ls -lSсортирует файл по размеру с некоторыми lsреализациями ( размер - число байтов в содержимом).
Стефан Шазелас

Ответы:

34

Вы должны использовать такую ​​команду:

find /group/book/four/word/ -type f -exec wc -l {} + | sort -rn
  • find: поиск файлов по нужному пути. Если вы не хотите, чтобы он был рекурсивным, и ваша findреализация его поддерживает, вы должны добавить его -maxdepth 1непосредственно перед -execопцией.
  • exec: указывает команде выполнить wc -lдля каждого файла.
  • sort -rn: отсортировать результаты численно в обратном порядке. От большего к низшему.

(предполагается, что имена файлов не содержат символов новой строки).

jherran
источник
Обратите внимание, что когда передано более одного файла (или в некоторых реализациях более одного файла, который он может прочитать), wcтакже будет напечатана totalстрока, поэтому здесь вы также получите одну или несколько «итоговых» строк, если только не один файл , Вы можете трубку, grep /чтобы удалить их.
Стефан Шазелас
upvote из-за sortкоманды
Франциско
Как я могу отфильтровать, чтобы показать только файл с минимумом строк X (исключить строку X = 0 для примера)?
Матрица
11

Нерекурсивна

Вероятно, самая простая версия, если вам не нужна рекурсивность:

wc -l /group/book/four/word/*|sort -n

wcподсчитывает количество строк (опция -l) в каждом (но скрытом) ( *) файле /group/book/four/word/и sortсортирует результат (через канал |) численно (опция -n).

рекурсивный

Кто-то сделал комментарий к этому ответу, упомянув grep -rlc, прежде чем его подавить. Действительно grepотличная альтернатива, особенно если вам нужна рекурсивность:

grep -rc '^' /group/book/four/word/|tr ':' ' '|sort -n -k2

будет считать (опция -c) рекурсивно (опция -r) строки, соответствующие ( grep) '^'(то есть, начало строк) в каталоге /group/book/four/word/. Затем вы должны заменить двоеточие пробелом, например, используя tr, чтобы помочь sort, который вы хотите отсортировать численно (опция -n) во втором столбце (опция -k2).

Обновление: см. Комментарий Стефана о возможных ограничениях и о том, как на самом деле можно избавиться tr.

Скиппи ле Гран Гуру
источник
3
grep -c .считает строки, которые содержат хотя бы один действительный символ. Используется grep -c '^'для подсчета всех строк (также будет подсчитывать завершающие символы после последней новой строки в некоторых grepреализациях). Обратите внимание, что не все grepреализации поддерживают a, -rи поведение отличается среди тех, которые поддерживают Вам не нужно переводить :s (двоеточие, а не точку с запятой) в пробелы для sort. Просто используйте -t:. Обратите внимание, что предполагается, что имена файлов не содержат :ни пробелов, ни символов новой строки.
Стефан Шазелас
1
Спасибо за размещение вашего нерекурсивного решения; Я не знал, wcдал бы такую ​​удобную сумму всего, если вы пройдете несколько путей. Объединение этой функциональности с диким символом и каналом sortдействительно чистое.
Qcom
7

С zsh:

lines() REPLY=$(wc -l < $REPLY)
printf '%s\n' /group/book/four/word/*(.no+lines)

Мы определяем новую функцию сортировки,lines которая отвечает количеству строк в файле. И мы используем o+linesквалификатор glob, который вместе с n(для числовой сортировки) определяет порядок упорядочения результатов glob. ( .также добавлен только для проверки обычных файлов).

Это не предполагает, какой символ могут содержать имена файлов, кроме скрытых файлов (те, которые начинаются с .). Добавьте Dспецификатор glob, если вы хотите их тоже.

Стефан Шазелас
источник
2
ОП отмечен bashтолько ...
l0b0
7
@ l0b0, это не значит, что следующий человек, которому это нужно, тоже будет запускать bash.
Terdon
4

Вы не указываете, хотите ли вы также файлы в каких-либо подкаталогах /group/book/four/word. findРешение в ответ jherran игровая спустится в подкаталоги. Если это не нужно, используйте вместо этого оболочку:

for file in ./*; do [ -f "$file" ] && wc -l "$file"; done | sort -n

Если ваши имена файлов могут содержать символы новой строки, вы можете использовать что-то вроде:

for file in ./*; do 
    [ -f "$file" ] && 
        printf "%lu %s\0" "$(wc -l < "$file")" "$file"
done | sort -zn | tr '\0' '\n'

И, наконец, если вы делаете покупку сходить в подкаталоги, вы можете использовать это в bash4 или выше:

shopt -s globstar
for file in ./**/*; do [ -f "$file" ] && wc -l "$file"; done | sort -n

Обратите внимание, что версии bashдо 4.3 следовали по символическим ссылкам при рекурсивном спуске дерева каталогов (например, zsh«s» или tcsh«s» ***/*).

Кроме того, все вышеприведенные решения будут игнорировать скрытые файлы (те, чье имя начинается с буквы «a» ., используйте их shopt -s dotglobдля включения), а также будут включать количество строк символических ссылок (чего findне будет в подходе).

Тердон
источник
Обратите внимание, что другие отличия от решения jherran заключаются в том, что вы также рассмотрите символическую ссылку на обычные файлы ( -xtype fв GNU find или *(-.)в zsh) и пропустите скрытые файлы.
Стефан Шазелас
@ StéphaneChazelas спасибо, уточнил. Почему %luв printf? Насколько я помню, это означает длинный беззнаковый десятичный знак, действительно ли это необходимо? Почему бы не рассматривать число как строку? Есть ли разница?
Тердон
2
Если вывод wc пуст (например, из-за того, что файл недоступен для чтения), то он расширится до 0пустой строки, что немного лучше. Некоторые реализации сортировки работают с целыми числами без знака, некоторые со знаком. %luзвучит как самая безопасная ставка, но это, вероятно, не имеет значения, если у вас есть 2^31линии, которые в любом случае потребуют возрастов.
Стефан Шазелас
1

Если вы хотите установить fdдействительно быстрый искатель файлов, написанный на Rust (вы должны установить его, в любом случае это здорово)

fd --type=file . | xargs wc -l | sort -n

В основном fdперечисляет файлы, xargs передает список файлов wc(обозначает количество слов, но, передавая -l, он подсчитывает количество строк), затем, наконец, сортируется по наименьшему количеству строк для наибольшего использования sort -n.

JustGage
источник