Jak sortować czytelny dla człowieka rozmiar

11

Zasadniczo szukam plików, a następnie sortuję według rozmiaru. Skrypt działa, jeśli nie posortuję rozmiaru według czytelnego dla człowieka. Ale chcę, żeby rozmiar był czytelny dla człowieka. Jak mogę sortować rozmiary, które są czytelne dla człowieka?

Na przykład:

 ls -l | sort -k 5 -n | awk '{print $9 " " $5}'

Działa to zgodnie z oczekiwaniami, rozmiar moich plików w bajtach rosnąco:

1.txt 1
test.txt 3
bash.sh* 573
DocGeneration.txt 1131
andres_stuff.txt 1465
Branches.xlsx 15087
foo 23735
bar 60566
2016_stuff.pdf 996850

Teraz chcę, aby rozmiar był czytelny dla człowieka, dlatego dodałem parametr -h do ls, a teraz niektóre pliki są nieczynne:

 ls -lh | sort -k 5 -n | awk '{print $9 " " $5}'
1.txt 1
DocGeneration.txt 1.2K
andres_stuff.txt 1.5K
test.txt 3
Branches.xlsx 15K
foo 24K
bar 60K
bash.sh* 573
2016_stuff.pdf 974K

tvo000
źródło
-k 5- Jak to działa?
ctrl-alt-delor
@ ctrl-alt-delor: Wydaje mi się, że rozmiar znajduje się w 5. kolumnie lswyniku
jesse_b
2
Używanie duzamiast lsmoże być dobrym pomysłem.
ksenoid
... lub find's -printfz jego %pi %sformaterami (po których następuje „humanizacja” rozmiarów).
Stephen Kitt
@Jesse_b mój błąd, po prostu założyłem, że dane w pytaniu (oznaczone jako to, co dostałem) były posortowanymi danymi wejściowymi.
ctrl-alt-delor

Odpowiedzi:

28

Próbować sort -h k2

-h, --human-numeric-sort porównaj liczby czytelne dla człowieka (np. 2K 1G)

Jest to część gnu sort, BSD sort i innych.

ctrl-alt-delor
źródło
5
Czy nie lsnależy unikać analizowania wyników ?
3
@Tomasz Nie zawsze. Jeśli zapewnia on potrzebne dane wyjściowe, przekazanie go do innej operacji formatowania nie jest szczególnie niebezpieczne. To, czego nie powinieneś robić, to zapętlić wyjście lsi zamiast tego użyć bezpośrednio globowania plików. Sam globbing tu nie zadziała. To powiedziawszy, prawdopodobnie wolałbym duto.
Bloodgain
1
@Bloodgain format ls nie jest gwarantowany, że jest taki sam w systemach binarnych system / ls, więc parsowanie go przenośnie jest uważane za niemożliwe.
D. Ben Knoble,
1
Nazwy
1
@Bloodgain: files=(); for f in *; do [[ -L "$f" ]] && files+=("$f"); done; echo ${#files[@]}(Mogę mieć nieprawidłowy przełącznik testu dowiązania symbolicznego). Jeśli nie obchodzą Cię dowiązania symboliczne, files=(*); echo ${#files[@]}które stają się przenośne, jeśli używasz, seta nie tablic.
D. Ben Knoble,
29

lsma wbudowaną tę funkcję, użyj -Sopcji i sortuj w odwrotnej kolejności:ls -lShr

       -r, --reverse
              reverse order while sorting

       -S     sort by file size, largest first
Mark McKinstry
źródło
1
-hnie jest standardową lsopcją , ale musi być użyteczna, jeśli OP już ją ma. Reszta jest standardowa i to z pewnością odpowiedź, którą bym napisał.
Toby Speight
5
+1 Nie zadzieraj podczas analizowania wyniku ls.
David Richerby
To najlepsza odpowiedź, ale powinna zawierać informacje w komentarzu @ Toby: -Smoże nie być dostępna dla ciebie ls. FWIW, -Sjest obsługiwany nawet z biblioteką Emacsa ls-lisp.el, która jest używana, gdy system operacyjny nie ma ls. Działa na przykład w Emacsie w MS Windows.
Drew
To powinna być zaakceptowana odpowiedź.
rozproszyć
1
@Drew: Komentarz Toby'ego mówi, że -hmoże nie być powszechnie dostępny, ale i tak już go używa. -Snaprawdę powinien być powszechnie dostępny, ponieważ znajduje się w łączu POSIX, który zapewnia Toby. Istnieje jednak sporo zestawów narzędzi innych niż POSIX.
Kevin
5

Ponieważ nie wymieniono żadnej konkretnej powłoki, oto jak to zrobić w zshpowłoce:

ls -lhf **/*(.Lk-1024oL)

**Wzór pasuje jak glob *, ale po drugiej stronie /w ścieżek, czyli jak rekurencyjny wyszukiwania zrobi.

lsKomenda pozwoliłoby ludzkich rozmiarów nieczytelne -h, a format długa lista z -l. Do -fwyłącza opcję sortowania, więc lsbędzie tylko listę plików w kolejności, w jakiej zostały podane.

Ta kolejność jest uporządkowana według **/*(.Lk-1024oL)wzorca globowania nazw plików, dzięki czemu mniejsze pliki są wyświetlane jako pierwsze. **/*Nieco pasuje każdy plik i katalog w katalogu i poniżej, ale (...)modyfikuje zachowanie Glob za (jest to „glob kwalifikator”).

Na oLkońcu uporządkuje ( o) nazwy według rozmiaru pliku ( L„długość”).

.Na początku sprawia, że glob pasuje tylko zwykłe pliki (bez katalogów).

Te Lk-1024pliki bitowe zaznaczane których rozmiar jest mniejszy niż 1024 KB ( „długość w KB mniej niż 1024”).

Jeśli zshnie jest to twoja podstawowa interaktywna powłoka, możesz użyć

zsh -c 'ls -lf **/*(.Lk-1024oL)'

Użyj setopt GLOB_DOTS(lub zsh -o GLOB_DOTS -c ...), aby dopasować również ukryte nazwy. ... lub po prostu dodaj Ddo ciągu kwalifikatora glob.


Rozwijając powyższe, zakładając, że chcesz 2-kolumnowy wynik z nazwami ścieżek i czytelnymi dla ludzi rozmiarami, a także zakładając, że masz numfmtz GNU coreutils,

zmodload -F zsh/stat b:zstat

for pathname in **/*(.Lk-1024oL); do
    printf '%s\t%s\n' "$pathname" "$(zstat +size "$pathname" | numfmt --to=iec)"
done

lub szybciej

paste <( printf '%s\n' **/*(.Lk-1024oL) ) \
      <( zstat -N +size **/*(.Lk-1024oL) | numfmt --to=iec )
Kusalananda
źródło
4

Jeśli sortnie masz takiej -hopcji, możesz użyć (choć bardzo długiego) polecenia awk, takiego jak:

find . -type f -size -1024k -exec ls -al {} \; | sort -k 5 -n | awk '{if ($5 > 1099511627776) {print $9,$5/1024/1024/1024/1024"T"} else if ($5 > 1073741824) {print $9,$5/1024/1024/1024"G"} else if ($5 > 1048576) {print $9,$5/1024/1024"M"} else if ($5 > 1024) {print $9,$5/1024"K"} else {print $9,$5"B"}}' | column -t

To posortuje dane wyjściowe w bajtach, a następnie przekonwertuje je na ich czytelny dla człowieka rozmiar.

jesse_b
źródło
-1

Czy to zadziała?

ls -l | awk '{if ($5<=1024) {print}}' | sort -k 5 -n | awk '{print $9"\t"substr($5/1024,1,3)"k"} '| column -t

Pierwszy awkexp szuka plików mniejszych niż 1M, a drugi pobiera rozmiar bajtu z wyniku i konwertuje go do KB i drukuje pierwsze 3 elementy, aby uzyskać rozmiar czytelny dla człowieka.

Vignesh SP
źródło
To tak naprawdę nie rozwiązuje pytania OP - tylko przegląda bieżący katalog i drukuje tylko zwykłe pliki. Porówna również z 1 KB zamiast 1 MB. Wreszcie jesteśmy po odpowiedziach z wyjaśnieniem, dlaczego kod działa.
grochmal
Mój zły dodał, co robi.
Vignesh SP