Список файлів, відсортований за кількістю рядків, які вони містять


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: сортувати результати чисельно у зворотному порядку. Від більшої до нижчої.

(що передбачає, що назви файлів не містять символів нового рядка).


Зауважте, що коли буде передано більше одного файлу (або з деякими реалізаціями, більше одного файлу, який він може прочитати), 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:. Зауважте, що припускаючи, що імена файлів не містять :чи пусті чи символи нового рядка.
Stéphane Chazelas

1
Дякуємо, що опублікували ваше нерекурсивне рішення; Я не знав, чи wcдав такий корисний загальний результат усім, якщо пройдеш кілька шляхів. З'єднання цієї функціональності з підключенням і підключенням sortдійсно чисте.
Qcom

7

З zsh:

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

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

Це не припускає, що імена файлів можуть містити інші, ніж приховані файли (ті, що починаються з .), опущені. Додайте Dглобальний кваліфікатор, якщо ви хочете і їх.


2
ОП позначено bashлише ...
l0b0

7
@ l0b0, це не означає, що наступна особа, яка потребує цього, також буде бігати.
тердон

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 або tcshs ***/*).

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


Зауважте, що інші відмінності від рішення jherran полягають у тому, що ваше також вважатиме посилання на звичайні файли ( -xtype fу GNU find або *(-.)в zsh) і опускатиме приховані файли.
Стефан Шазелас

@ StéphaneChazelas спасибі, уточнив. Чому %luв printf? Наскільки я пам’ятаю, це означає довгий неподписаний десятковий, чи справді це потрібно? Чому б не трактувати число як рядок? Чи має значення це?
terdon

2
Якщо вихід wc порожній (наприклад, через те, що файл не читається), то він розшириться на 0замість порожнього рядка, що трохи краще. Деякі варіанти реалізації працюють з непідписаними цілими числами, а деякі з підписаними. %luзвучить як найбезпечніша ставка, але це, мабуть, не має значення, як якщо у вас є 2^31рядки, які все одно пройдуть віки.
Стефан Шазелас

1

Якщо ви хочете встановити fdсправді швидкий пошук файлів, написаний на Rust (вам слід встановити його, все одно здорово)

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

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

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