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:
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.
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.
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.
@ 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:
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.
ls -l
nie podaje liczby linii.ls -lS
sortuje plik według rozmiaru za pomocą niektórychls
implementacji ( rozmiar jest liczbą bajtów w treści).Odpowiedzi:
Powinieneś użyć następującego polecenia:
find
: wyszukaj pliki na wybranej ścieżce. Jeśli nie chcesz, aby był rekurencyjny, a twojafind
implementacja go obsługuje, powinieneś dodać-maxdepth 1
tuż przed-exec
opcją.exec
: nakazuje wykonanie polecenia dlawc -l
każ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).
źródło
wc
również wydrukujetotal
wiersz, więc tutaj otrzymasz również jeden lub więcej „łącznych” wierszy, chyba że jest tylko jeden plik . Możesz potokować, abygrep /
je usunąć.sort
komendąBrak rekurencji
Prawdopodobnie najprostsza wersja, jeśli nie potrzebujesz rekurencyjności:
wc
zlicza linie (opcja-l
) w każdym (ale ukrytym) (*
) pliku poniżej/group/book/four/word/
isort
sortuje wynik (przez potok|
) numerycznie (opcja-n
).Rekurencyjne
Ktoś skomentował tę odpowiedź, wspominając o niej
grep -rlc
, zanim ją stłumi. Rzeczywiściegrep
jest świetną alternatywą, szczególnie jeśli potrzebujesz rekurencyjności: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ąctr
, aby pomócsort
, 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
.źródło
grep -c .
zlicza wiersze zawierające co najmniej jeden poprawny znak. Służygrep -c '^'
do zliczania wszystkich linii (w przypadku niektórychgrep
implementacji policzy także końcowe znaki po ostatniej nowej linii ). Należy pamiętać, że nie wszystkiegrep
implementacje obsługują a,-r
a zachowanie różni się między tymi, które to robią. Nie musisz tłumaczyć:
s (dwukropka, nie średnika) na spacje dlasort
. Po prostu użyj-t:
. Zauważ, że przy założeniu, że nazwy plików nie zawierają:
ani znaków pustych ani nowego wiersza.wc
podałem tak poręczną sumę, jeśli przejdziesz wiele ścieżek. Połączenie tej funkcjonalności z dziką kartą i potokiemsort
jest naprawdę czyste.Z
zsh
:Definiujemy nową funkcję sortowania,
lines
która odpowiada liczbą wierszy w pliku. I używamyo+lines
kwalifikatora glob, który wraz zn
(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. DodajD
kwalifikator glob, jeśli chcesz.źródło
bash
tylko ...Nie określasz, czy chcesz również pliki w podkatalogach
/group/book/four/word
.find
Rozwiązanie w odpowiedzi jherran będzie zejść do podkatalogów. Jeśli nie jest to potrzebne, zamiast tego użyj powłoki:Jeśli twoje nazwy plików mogą zawierać znaki nowej linii, możesz użyć czegoś takiego:
Wreszcie, jeśli zrobić chcą zejść do podkatalogów, można to wykorzystać w
bash
4 lub powyżej:Zauważ, że wersje
bash
wcześniejsze niż 4.3 podążały za dowiązaniami symbolicznymi, gdy rekurencyjnie schodziły do drzewa katalogów (takich jakzsh
„stcsh
”***/*
).Ponadto wszystkie powyższe rozwiązania będą ignorować ukryte pliki (te, których nazwa zaczyna się od
.
, użyj,shopt -s dotglob
aby je uwzględnić), a także zawierać liczbę wierszy dowiązań symbolicznych (czegofind
podejście nie będzie).źródło
-xtype f
w GNU find lub*(-.)
w zsh) i pominie ukryte pliki.%lu
wprintf
? 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ę?0
zamiast pustego ciągu, co jest nieco lepsze. Niektóre implementacje sortowania działają z liczbami całkowitymi bez znaku, niektóre z podpisanymi.%lu
brzmi jak najbezpieczniejszy zakład, ale prawdopodobnie nie ma to znaczenia, jakbyś miał2^31
linie, które i tak potrwają wieki.Jeśli chcesz zainstalować
fd
naprawdę szybką wyszukiwarkę plików napisaną w Rust (powinieneś ją zainstalować, i tak warto ją mieć)Zasadniczo
fd
wyświetla listę plików, xargs przekaże listę plikówwc
(oznacza liczbę słów, ale przekazanie -l spowoduje, że zliczą linie), a następnie posortowane od najmniejszej liczby wierszy do największejsort -n
.źródło