Como classificar o tamanho legível por humanos

11

Basicamente, estou procurando arquivos e, em seguida, classificando pelo tamanho. O script funciona se eu não classificar o tamanho por legível por humanos. Mas quero que o tamanho seja legível por humanos. Como posso classificar tamanhos legíveis por humanos?

Por exemplo:

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

Isso funciona como esperado, eu tenho o tamanho dos meus arquivos em bytes crescente:

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

Agora, eu quero que o tamanho seja legível por humanos, então adicionei um parâmetro -h a ls e agora alguns arquivos estão fora de ordem:

 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
fonte
-k 5- como isso funciona?
Ctrl-alt-delor 13/06/19
@ ctrl-alt-Delor: Eu acredito que o tamanho é na quinta coluna da lssaída
jesse_b
2
Usar em duvez de lspode ser uma boa ideia.
xenoid 13/06/19
... ou find's -printfcom a sua %pe %sformatadores (seguido por uma ‘humanização’ dos tamanhos).
Stephen Kitt
@ Jessie_b meu erro, eu apenas assumi que os dados na pergunta (marcado como isto é o que eu obtive) foram os dados ordenados. Eu estava errado.
Ctrl-alt-delor 13/06/19

Respostas:

28

Experimentar sort -h k2

-h, --human-numeric-sort compara números legíveis por humanos (por exemplo, 2K 1G)

Faz parte do tipo gnu, tipo BSD e outros.

ctrl-alt-delor
fonte
5
A análise da saída não deve lsser evitada?
3
@ Tomasz Nem sempre. Se fornecer a saída necessária, canalizá-la para outra operação de formatação não é particularmente perigosa. O que você não deve fazer é fazer um loop sobre a saída lse usar o globbing de arquivo diretamente. Globbing sozinho não vai funcionar aqui. Dito isto, eu provavelmente preferiria duisso.
Bloodgain
1
@Bloodgain não é garantido que o formato ls seja o mesmo nos binários dos sistemas / ls, portanto, analisá-lo de forma portável é considerado impossível.
D. Ben Knoble
1
Além disso, nomes de arquivos com espaço em branco irão alterar as coisas
D. Ben Knoble 17/06/19
1
@ Bloodgain: files=(); for f in *; do [[ -L "$f" ]] && files+=("$f"); done; echo ${#files[@]}(Eu posso ter o interruptor de teste symlink errado). Se você não se importa com links simbólicos,, files=(*); echo ${#files[@]}que se torna portátil se você usar sete não matrizes.
D. Ben Knoble,
29

lspossui essa funcionalidade, use a -Sopção e classifique na ordem inversa:ls -lShr

       -r, --reverse
              reverse order while sorting

       -S     sort by file size, largest first
Mark McKinstry
fonte
1
-hnão é uma opção padrãols , mas deve ser utilizável se o OP já a possuir. O resto é padrão, e certamente é a resposta que eu teria escrito.
precisa
5
+1 Não mexa na análise da saída de ls.
David Richerby
Esta é a melhor resposta, mas deve incluir as informações no comentário do @ Toby: -Spode não estar disponível para o seu ls. O FWIW -Sé suportado mesmo com a biblioteca do Emacs ls-lisp.el, que é usada quando o sistema operacional não possui ls. Ele funciona no Emacs no MS Windows, por exemplo.
Tirou
Essa deve ser a resposta aceita.
scatter
1
@ Drew: O comentário de Toby diz que -hpode não estar disponível universalmente, mas a OP já está usando de qualquer maneira. -Srealmente deve estar disponível universalmente, porque está no link POSIX que Toby fornece. No entanto, existem muitos kits de ferramentas não POSIX por aí.
Kevin
5

Como nenhum shell específico foi mencionado, veja como fazer a coisa toda no zshshell:

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

O **padrão glob corresponde a nomes de caminho semelhantes, *mas /cruzados, ou seja, como uma pesquisa recursiva faria.

O lscomando permitiria tamanhos legíveis por humanos com -h, e formato de saída de lista longa com -l. A -fopção desativa a classificação, portanto ls, basta listar os arquivos na ordem em que são fornecidos.

Essa ordem é organizada pelo **/*(.Lk-1024oL)padrão de globbing do nome do arquivo, para que os arquivos menores sejam listados primeiro. O **/*bit corresponde a todos os arquivos e diretórios neste diretório e abaixo, mas (...)modifica o comportamento da glob (é um "qualificador da glob").

É oLo final que ordena ( o) os nomes por tamanho de arquivo ( L, "comprimento").

No .início, o glob corresponde apenas aos arquivos regulares (sem diretórios).

O Lk-1024bit seleciona arquivos cujo tamanho é menor que 1024 KB ("comprimento em KB menor que 1024").

Se zshnão for seu shell interativo principal, você poderá usar

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

Use setopt GLOB_DOTS(ou zsh -o GLOB_DOTS -c ...) para também corresponder nomes ocultos. ... ou apenas adicione Dà cadeia qualificadora glob.


Expandindo o exposto acima, supondo que você deseje uma saída de 2 colunas com nomes de caminho e tamanhos legíveis por humanos, e também assumindo que você possui os numfmtcoreutils do GNU,

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

ou, mais rápido,

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

Se o seu sortnão tiver a -hopção, você poderá usar um comando (ainda que muito longo) do awk como o seguinte:

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

Isso classificará sua saída em bytes e depois a converterá em seu tamanho legível por humanos posteriormente.

jesse_b
fonte
-1

Isso funcionaria?

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

A primeira awkexp procurará os arquivos com menos de 1 milhão e a segunda pegará o tamanho de byte do resultado e a converterá para o KB e imprimirá os 3 primeiros elementos para fornecer um tamanho legível por humanos.

Vignesh SP
fonte
Isso realmente não resolve a questão dos OPs - ele apenas procura no diretório atual e apenas imprime arquivos regulares. Também será comparado com 1 KB em vez de 1 MB. Finalmente, buscamos respostas com algumas explicações sobre por que o código funciona.
grochmal
Meu mal adicionou o que faz.
Vignesh SP