Eu tenho um alias simples para listar o tamanho dos arquivos e pastas no cwd.
(incluindo dotfiles neste caso, ignorando tamanhos zero)
du -sh .[!.]* * | sort -hr | grep -v '^0'
o que também pode ser alcançado com find:
find .[!.]* * -maxdepth 0 -exec du -sh {} \; | sort -hr | grep -v '^0'
saída de exemplo:
// .ssh & .byobu are folders - .zsh* are files
// currently not able to distinguish them by type
...
32K .zshrc
25K .ssh
20K .zcompdump
19K .byobu
...
Como posso colorir os arquivos/diretórios na saída correspondendo às cores ls?(LS_COLORS)
Responder1
Este zsh
script analisa $LS_COLORS
. Ele precisa apenas de uma stat
chamada para cada arquivo e, portanto, é muito mais rápido que a solução abaixo, que chama ls
todos os arquivos. E lida corretamente com arquivos com espaços. ( \n
ou \t
ainda estãonãopermitido em nomes de arquivos)
No entanto, a implementação não está completa. Incluí apenas cores para diferentes tipos de arquivos que podem ser identificados pelo primeiro caractere da string do modo de arquivo (por exemplo, lrwxrwxrwx
para um link simbólico) ou pela extensão do arquivo. Isso significa que as permissões graváveis em todo o mundo, suid ou bits pegajosos não são coloridos de maneira especial. Incluí-los também deve ser simples.
source
o seguinte e use a nova função shell duc
para uma du
saída colorida:
zmodload -F zsh/stat b:zstat
function duc() {
emulate zsh
setopt no_nomatch interactivecomments # no_nomatch is necessary, to prevent error in "do .* *" if there are no dotfiles
typeset -a aline
typeset -A lscols
local dircols acolor
for i (${(s.:.)LS_COLORS}) { # split $LS_COLORS at ":"
aline=(${(s:=:)i}) # split every entry at "="
lscols+=(${${aline[1]}/*.} ${aline[2]}) # load every entry into the associative array $lscols
}
duout=$(du -sh .* * 2> /dev/null | grep -v '^0' | sort -hr)
for i (${(f)duout}) { # split output of "du" at newlines
aline=(${(ps:\t:)i}) # split every entry at \t
zstat -s +mode -A atype ${aline[2]} # determine mode (e.g. "drwx------") of file ${aline[2]}
case ${${atype[1]}[1]} in # ${${atype[1]}[1]} is the first character of the file mode
b) acolor=$lscols[bd] ;;
c|C) acolor=$lscols[cd] ;;
d) acolor=$lscols[di] ;;
l) acolor=$lscols[ln] ;;
p) acolor=$lscols[pi] ;;
s) acolor=$lscols[so] ;;
-) acolor=${lscols[${${aline[2]}:e}]}; # ${${aline[2]}:e} is the current file extention
[[ -z $acolor ]] && acolor=$lscols[fi] # unrecognized extention
[[ -z $acolor ]] && acolor=00 # sometimes "fi" isn't set in $LS_COLORS, so fall back to normal color
;;
*) acolor=00 ;;
esac
print -n -- "${aline[1]}\t" # print size (taken from du output)
print -n "\\e[4${acolor}m" # activate color
print -n ${aline[2]} # print file name
print "\\e[0m" # deactivate color
}
}
Este é meu script antigo, também para zsh
. Provavelmente é desnecessariamente complexo e muito lento, pois para cada arquivo ls
é emitido um único comando:
du_colored() {
typeset -a duout
duout=($(du -sh .* * | sort -hr | grep -v '^0'))
for i ({1..$#duout..2}) {
print -n "${duout[$i]}\t"
ls -d --color ${duout[$(($i+1))]}
}
}
- o
.*
testamentozsh
nãomatch.
ou..
, mas arquivos como..foo
which serão perdidos com.[!.]*
typeset -a
declara uma matriz- os loops for no array,
$i
assume valores de 1 em diante em etapas de 2
Aviso: Isso irá quebrar muito quando houver arquivos comespaços em branco... Não tenho ideia melhor no momento.
Responder2
Isto é o que eu criei para o bash - usa pv para mostrar o progresso da saída
folder_size (){
# read ls --color output into ls_colored_array
# thereby remove symlinks (@) and remove (/ and *) from folders and files
ls -AF --color | grep -v @ | sed s'/[/\,*]$//'| xargs -n1 -L1 | read -d '\n' -r -a ls_colored_array
# - loop over the array and issue du -sh for every element
# - exchange du's ouput with ls's
# - run loop through pv with line option and
# size set to array-length showing progress
# - finally sort the output using sort
for i in "${ls_colored_array[@]}"; do
echo -n "${i}" | sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g" | xargs -n1 -0 du -sh | awk -v i="$i" '{ printf "%-10s ", $1; $1=""; print i }'
done | pv -pls"${#ls_colored_array[@]}" | sort -hr
}
O script agora pode ser transformado em uma linha ... mas vou melhorar a função adicionando sinalizadores para, ou seja, 10 arquivos/pastas maiores ou apenas pastas.
Responder3
Isso funciona para mim:
#!/usr/bin/env bash
paste <(du --apparent-size --all --human-readable --max-depth=1 2>/dev/null |
sed 's/\s.*//') \
<(ls --color=always -1 --almost-all -U) | sort --human-numeric-sort
O comando principal aqui é paste
, ele unirá as saídas de ls
e du
horizontalmente.
du
produzirá cada linha mais ou menos assim:
147291 ./.config
sed 's/\s.*//
irá deletar tudo depois e inclusive o primeiro espaço, ou seja, ./.config
já que não estamos interessados nas formas não coloridas dos nomes das entradas listadas. O truque aqui é gerar ls
o conteúdo do diretório da mesma maneira que du
podemos unir facilmente cada entrada com seu tamanho correspondente. Podemos fazer isso com a ajuda de -1
(que lista as entradas verticalmente em vez de horizontalmente), -U
(que lista as entradas em ordem de diretório, assim como du
, em vez de alfabeticamente) e --almost-all
(que lista diretórios/arquivos ocultos também, mas deixa de fora .
e ..
em oposição a --all
) e claro --color=always
. Para du
, --all
é necessário fazer com que ele processe arquivos (incluindo os ocultos) e diretórios em vez de apenas diretórios, e --max-depth=1
pare du
de operar em subdiretórios (assim find
como -maxdepth 1
)
Portanto, para responder à pergunta, basta o seguinte:
paste <(du --all --max-depth=1 | sed 's/\s.*//') \
<(ls --color=always -1 --almost-all -U)
Quanto aos outros argumentos opcionais:
--apparent-size
tornadu
os tamanhos de impressão aparentes, em vez do uso do disco (minha preferência)--human-readable
imprime tamanhos legíveis por humanos2>/dev/null
filtra quaisquerpermission denied
erros se você tentou executardu
em um diretório restrito, por exemplo/var
sort --human-numeric-sort
classifica os tamanhos em ordem decrescente,--human-numeric-sort
é necessário se--human-readable
for passado paradu
Responder4
Combinar algumas das respostas acima com oh-my-zshell em um Mac me forneceu tamanhos, nomes de diretórios coloridos e nomes de arquivos de texto simples classificados para gerar os 10 maiores arquivos/diretórios:
paste <(du -cks *) <(ls --color=always -1) | sort -nr | head | awk '{print $1 " " $3}'
Explicação:
du
para uso do disco -c:grand total -k: 1Kb blocks -s: entry
para cada arquivo;
ls
para pegar a cor dos diretórios;
paste
combinar ambos os resultados acima;
sort -nr
: classificação reversa numérica;
head
: gera os maiores arquivos/diretórios;
awk
: para gerar apenas a primeira coluna (tamanho) e a terceira coluna (arquivo/nome do diretório colorido)