Tengo un alias simple para enumerar el tamaño de archivos y carpetas en cwd.
(incluidos los archivos de puntos en este caso, ignorando los tamaños cero)
du -sh .[!.]* * | sort -hr | grep -v '^0'
que también se puede lograr con find:
find .[!.]* * -maxdepth 0 -exec du -sh {} \; | sort -hr | grep -v '^0'
salida de ejemplo:
// .ssh & .byobu are folders - .zsh* are files
// currently not able to distinguish them by type
...
32K .zshrc
25K .ssh
20K .zcompdump
19K .byobu
...
¿Cómo puedo colorear los archivos/directorios en la salida que coincidan con los colores de ls?(LS_COLORS)
Respuesta1
Este zsh
script analiza $LS_COLORS
. Sólo necesita una stat
llamada a cada archivo y, por lo tanto, es mucho más rápida que la solución en la parte inferior, que llama ls
a cada archivo. Y maneja archivos con espacios correctamente. ( \n
o \t
todavía estánnopermitido en nombres de archivos)
Sin embargo, la implementación no está completa. Sólo incluí colores para diferentes tipos de archivos que pueden identificarse por el primer carácter de la cadena del modo de archivo (por ejemplo, lrwxrwxrwx
para un enlace simbólico) o por la extensión del archivo. Esto significa que los permisos de escritura mundial, los bits suid o adhesivos no tienen colores especiales. Incluirlos también debería ser sencillo.
source
lo siguiente y use la nueva función Shell duc
para una du
salida en color:
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 es mi antiguo script, también para zsh
. Probablemente sea innecesariamente complejo y muy lento, ya que para cada archivo ls
se emite un ú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))]}
}
}
- el
.*
enzsh
voluntadnocoincide con.
o..
, pero archivos como..foo
el cual se perderán con.[!.]*
typeset -a
declara una matriz- los bucles for aver la matriz,
$i
toma valores de 1 en adelante en pasos de 2
Advertencia: Esto se romperá gravemente cuando haya archivos conespacios en blanco... No tengo una mejor idea en este momento.
Respuesta2
Esto es lo que se me ocurrió para bash: usa pv para mostrar el progreso de la salida
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
}
El script ahora se puede convertir en una sola línea... pero mejoraré la función agregando indicadores para, por ejemplo, 10 archivos/carpetas más grandes o solo carpetas.
Respuesta3
Esto funciona para mí:
#!/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
El comando principal aquí es paste
unirá las salidas de ls
y du
horizontalmente.
du
generará cada línea algo como esto:
147291 ./.config
sed 's/\s.*//
eliminará todo lo que sigue al primer espacio incluido, es decir, ./.config
ya que no estamos interesados en las formas sin color de los nombres de las entradas enumeradas. El truco aquí es generar ls
el contenido del directorio de la misma manera du
para que podamos unir sin esfuerzo cada entrada con su tamaño correspondiente. Podemos hacerlo con la ayuda de -1
(que enumera las entradas verticalmente en lugar de horizontalmente), -U
(que enumera las entradas en orden de directorio, como du
en lugar de alfabéticamente) y --almost-all
(que también enumera directorios/archivos ocultos, pero omite .
y ..
en lugar de --all
) y por supuesto --color=always
. Para du
, --all
es necesario hacer que procese tanto archivos (incluidos los ocultos) como directorios en lugar de solo directorios, y --max-depth=1
deja du
de operar en subdirectorios (como find
en -maxdepth 1
)
Entonces, para responder a la pregunta, sólo se necesita lo siguiente:
paste <(du --all --max-depth=1 | sed 's/\s.*//') \
<(ls --color=always -1 --almost-all -U)
En cuanto a los otros argumentos opcionales:
--apparent-size
hace quedu
los tamaños de impresión sean aparentes, en lugar del uso del disco (mi preferencia)--human-readable
imprime tamaños legibles por humanos2>/dev/null
filtra cualquierpermission denied
error si intentó ejecutardu
en un directorio restringido, por ejemplo/var
sort --human-numeric-sort
clasifica los tamaños en orden descendente,--human-numeric-sort
es necesario si--human-readable
se pasa adu
Respuesta4
La combinación de algunas de las respuestas anteriores con oh-my-zshell en una Mac me proporcionó tamaños, nombres de directorios coloreados y nombres de archivos de texto sin formato ordenados para generar los 10 archivos/directorios más grandes:
paste <(du -cks *) <(ls --color=always -1) | sort -nr | head | awk '{print $1 " " $3}'
Explicación:
du
para el uso del disco -c:grand total -k: 1Kb blocks -s: entry
para cada archivo;
ls
tomar el color de los directorios;
paste
combinar ambos resultados anteriores;
sort -nr
: clasificación inversa numérica;
head
: genera archivos/directorios más grandes;
awk
: para generar solo la primera columna (tamaño) y la tercera columna (nombre de archivo/directorio coloreado)