
Se eu executar o comando, du -ah | sort -nr
é possível mostrar qual linha na saída é um arquivo e qual pasta? Algo como o comando ls -l
mostra qual é o arquivo e a pasta com d
e -
na frente.
Responder1
É possível, mas não sem a ajuda de outro comando. Especificamente, aqui estamos usando o GNU awk (isso é importante, então verifique sua versão do awk)
$ du -ah | sort -nr | awk '{usage=$1; $1="";cmd="file "$0;cmd |& getline type;print usage,type ;close(cmd)}'
24K .: directory
4.0K ./testdir: directory
4.0K ./out.txt: ASCII text
4.0K ./3.txt: ASCII text
4.0K ./2.txt: ASCII text
4.0K ./1.txt: ASCII text
É claro que esta abordagem é um pouco falha, pois parece falhar com nomes de arquivos que contêm espaços (ainda trabalhando para melhorá-la).
Como alternativa, também podemos usar find
o comando para encontrar todos os arquivos e executar file
e du
os comandos para fazer nossos lances via -exec
flag, mas isso parece um pouco feio (veja o histórico de edições). Poderíamos, no entanto, usar find
o -printf
sinalizador para imprimir o tipo de arquivo com %y
formato para uma saída muito mais bonita.
$ find -mindepth 1 -printf "%y\t" -exec du "{}" \; | sort -rn
f 4 ./out.txt
f 4 ./3.txt
f 4 ./2.txt
f 4 ./1.txt
f 0 ./with space.txt
d 4 ./testdir
Obviamente aqui f
é para arquivo normal e d
para diretório. Consulte find
o manual do para obter mais informações sobre sinalizadores e letras de tipo de arquivo
Responder2
Como diz Serg, du
não posso fazer isso sozinho. Para processar nomes de arquivos com segurança, a melhor maneira é separá-los com o caractere nulo ASCII ( \0
), e du
pode fazerque. Então, usando isso, junto com sort
a xargs
capacidade de lidar com entradas delimitadas por nulos:
du -0ah |
sort -zh |
xargs -0 sh -c 'for i; do s=${i%%[[:space:]]*};f=${i#*[[:space:]]}; echo "$s" "$(ls --color -dF "$f")"; done' _
As opções -0
, -z
e -0
informam du
e sort
para xargs
usar ASCII nul como separador.
Depois, s=${i%[[:space:]]*}
para obter o início da linha até o espaço em branco (que é o tamanho) e f=${i#*[[:space:]]}
obter todo o resto (o nome do arquivo). Depois imprimimos ls
o nome do arquivo com decoração.
Exemplo:
$ du -0ah Screenshots | sort -zh | xargs -0 sh -c 'for i; do s=${i%%[[:space:]]*};f=${i#*[[:space:]]}; echo "$s" "$(ls --color -dF "$f")"; done' _
512 Screenshots/desktop.ini*
264K Screenshots/Screenshot (1).png*
269K Screenshots/
Como usei ls --color
, também obtenho uma boa saída de cores: