Lista plików posortowana według liczby zawartych w nich linii


32

Jak mogę wyświetlić liczbę linii w plikach /group/book/four/word, posortowaną według liczby linii, które zawierają?

ls -l polecenie wyświetla je w dół, ale ich nie sortuje


1
Czy chcesz, aby pliki były wymienione według liczby wierszy, czy podaj liczbę wierszy w plikach, czy oba? ls -lnie podaje liczby linii. ls -lSsortuje plik według rozmiaru za pomocą niektórych lsimplementacji ( rozmiar jest liczbą bajtów w treści).
Stéphane Chazelas

Odpowiedzi:


34

Powinieneś użyć następującego polecenia:

find /group/book/four/word/ -type f -exec wc -l {} + | sort -rn
  • find: wyszukaj pliki na wybranej ścieżce. Jeśli nie chcesz, aby był rekurencyjny, a twoja findimplementacja go obsługuje, powinieneś dodać -maxdepth 1tuż przed -execopcją.
  • exec: nakazuje wykonanie polecenia dla wc -lkażdego pliku.
  • sort -rn: sortuj wyniki numerycznie w odwrotnej kolejności. Od większego do niższego.

(przy założeniu, że nazwy plików nie zawierają znaków nowej linii).


Zauważ, że po przekazaniu więcej niż jednego pliku (lub w przypadku niektórych implementacji, więcej niż jednego pliku, który może odczytać), wcrównież wydrukuje totalwiersz, więc tutaj otrzymasz również jeden lub więcej „łącznych” wierszy, chyba że jest tylko jeden plik . Możesz potokować, aby grep /je usunąć.
Stéphane Chazelas

głosowanie za sortkomendą
Francisco

jak mogę filtrować, aby wyświetlać tylko plik z minimum X linii (wyklucz przykład X = 0 dla przykładu)?
Matryca

11

Brak rekurencji

Prawdopodobnie najprostsza wersja, jeśli nie potrzebujesz rekurencyjności:

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

wczlicza linie (opcja -l) w każdym (ale ukrytym) ( *) pliku poniżej /group/book/four/word/i sortsortuje wynik (przez potok |) numerycznie (opcja -n).

Rekurencyjne

Ktoś skomentował tę odpowiedź, wspominając o niej grep -rlc, zanim ją stłumi. Rzeczywiście grepjest świetną alternatywą, szczególnie jeśli potrzebujesz rekurencyjności:

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

policzy (opcja -c) rekurencyjnie (opcja -r) wiersze pasujące ( grep) '^'(czyli początek linii) w katalogu /group/book/four/word/. Następnie musisz zastąpić dwukropek spacją, np. Używając tr, aby pomóc sort, którą chcesz posortować numerycznie (opcja -n) w drugiej kolumnie (opcja -k2).

Aktualizacja: Zobacz komentarz Stephane'a na temat możliwych ograniczeń i tego, jak możesz się go pozbyć tr.


3
grep -c .zlicza wiersze zawierające co najmniej jeden poprawny znak. Służy grep -c '^'do zliczania wszystkich linii (w przypadku niektórych grepimplementacji policzy także końcowe znaki po ostatniej nowej linii ). Należy pamiętać, że nie wszystkie grepimplementacje obsługują a, -ra zachowanie różni się między tymi, które to robią. Nie musisz tłumaczyć :s (dwukropka, nie średnika) na spacje dla sort. Po prostu użyj -t:. Zauważ, że przy założeniu, że nazwy plików nie zawierają :ani znaków pustych ani nowego wiersza.
Stéphane Chazelas

1
Dziękujemy za opublikowanie swojego nierekurencyjnego rozwiązania; Nie wiedziałem, że wcpodałem tak poręczną sumę, jeśli przejdziesz wiele ścieżek. Połączenie tej funkcjonalności z dziką kartą i potokiem sortjest naprawdę czyste.
Qcom,

7

Z zsh:

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

Definiujemy nową funkcję sortowania,lines która odpowiada liczbą wierszy w pliku. I używamy o+lineskwalifikatora glob, który wraz z n(do sortowania numerycznego) określa, w jaki sposób uporządkowane są wyniki globu. ( .dodany również w celu sprawdzenia zwykłych plików).

Nie zakłada to, jaki znak nazwy plików mogą zawierać inne niż pliki ukryte (te zaczynające się od .) są pomijane. Dodaj Dkwalifikator glob, jeśli chcesz.


2
OP jest oznaczony bashtylko ...
l0b0

7
@ l0b0, co nie oznacza, że ​​następna osoba, która będzie tego potrzebować, również uruchomi bash.
terdon

4

Nie określasz, czy chcesz również pliki w podkatalogach /group/book/four/word. findRozwiązanie w odpowiedzi jherran będzie zejść do podkatalogów. Jeśli nie jest to potrzebne, zamiast tego użyj powłoki:

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

Jeśli twoje nazwy plików mogą zawierać znaki nowej linii, możesz użyć czegoś takiego:

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

Wreszcie, jeśli zrobić chcą zejść do podkatalogów, można to wykorzystać w bash4 lub powyżej:

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

Zauważ, że wersje bashwcześniejsze niż 4.3 podążały za dowiązaniami symbolicznymi, gdy rekurencyjnie schodziły do ​​drzewa katalogów (takich jak zsh„s tcsh***/*).

Ponadto wszystkie powyższe rozwiązania będą ignorować ukryte pliki (te, których nazwa zaczyna się od ., użyj, shopt -s dotglobaby je uwzględnić), a także zawierać liczbę wierszy dowiązań symbolicznych (czego findpodejście nie będzie).


Zauważ, że inne różnice w stosunku do rozwiązania jherran są takie, że twoje rozważy również dowiązanie symboliczne do zwykłych plików ( -xtype fw GNU find lub *(-.)w zsh) i pominie ukryte pliki.
Stéphane Chazelas

@ StéphaneChazelas dzięki, wyjaśnione. Dlatego %luw printf? O ile pamiętam, to oznacza długi dziesiętny bez znaku, czy to naprawdę konieczne? Dlaczego nie traktować liczby jako ciągu? Czy to robi różnicę?
terdon

2
Jeśli wyjście wc jest puste (na przykład dlatego, że pliku nie można odczytać), zostanie ono rozwinięte 0zamiast pustego ciągu, co jest nieco lepsze. Niektóre implementacje sortowania działają z liczbami całkowitymi bez znaku, niektóre z podpisanymi. %lubrzmi jak najbezpieczniejszy zakład, ale prawdopodobnie nie ma to znaczenia, jakbyś miał 2^31linie, które i tak potrwają wieki.
Stéphane Chazelas

1

Jeśli chcesz zainstalować fdnaprawdę szybką wyszukiwarkę plików napisaną w Rust (powinieneś ją zainstalować, i tak warto ją mieć)

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

Zasadniczo fdwyświetla listę plików, xargs przekaże listę plików wc(oznacza liczbę słów, ale przekazanie -l spowoduje, że zliczą linie), a następnie posortowane od najmniejszej liczby wierszy do największej sort -n.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.