Ich habe einen einfachen Alias, um die Größe von Dateien und Ordnern in cwd aufzulisten.
(in diesem Fall einschließlich Dotfiles, Nullgrößen werden ignoriert)
du -sh .[!.]* * | sort -hr | grep -v '^0'
was auch mit find erreicht werden kann:
find .[!.]* * -maxdepth 0 -exec du -sh {} \; | sort -hr | grep -v '^0'
Beispielausgabe:
// .ssh & .byobu are folders - .zsh* are files
// currently not able to distinguish them by type
...
32K .zshrc
25K .ssh
20K .zcompdump
19K .byobu
...
Wie kann ich die Dateien/Verzeichnisse in der Ausgabe passend zu den LS-Farben einfärben?( LS_COLORS )
Antwort1
Dieses zsh
Skript analysiert $LS_COLORS
. Es muss nur stat
für jede Datei aufgerufen werden und ist daher viel schneller als die Lösung unten, die ls
für jede Datei aufruft. Und es verarbeitet Dateien mit Leerzeichen korrekt. ( \n
oder \t
sind immer nochnichtin Dateinamen erlaubt)
Die Implementierung ist jedoch nicht vollständig. Ich habe nur Farben für verschiedene Dateitypen aufgenommen, die am ersten Zeichen des Dateimodus-Strings (z. B. lrwxrwxrwx
für einen symbolischen Link) oder an der Dateierweiterung identifiziert werden können. Das bedeutet, dass allgemein schreibbare Berechtigungen, Suid- oder Sticky-Bits nicht speziell eingefärbt werden. Diese ebenfalls einzubinden sollte unkompliziert sein.
source
Folgendes und verwenden Sie die neue Shell-Funktion duc
für eine farbige du
Ausgabe:
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
}
}
Dies ist mein altes Skript, auch für zsh
. Es ist wahrscheinlich unnötig komplex und wirklich langsam, da für jede Datei ein einzelner ls
Befehl ausgegeben wird:
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))]}
}
}
- das
.*
inzsh
wirdnichtmatch.
oder..
, aber Dateien wie..foo
which werden mit.[!.]*
typeset -a
deklariert ein Array- die for-Schleifen durchlaufen das Array und
$i
nehmen Werte ab 1 in 2er-Schritten an
Warnung: Dies wird schlecht funktionieren, wenn es Dateien mitRohlinge... mir fällt im Moment keine bessere Idee ein.
Antwort2
Das ist, was ich mir für Bash ausgedacht habe – verwendet PV, um den Ausgabefortschritt anzuzeigen
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
}
Das Skript kann jetzt in eine Einzeilerzeile umgewandelt werden … aber ich werde die Funktion verbessern, indem ich Flags für z. B. die 10 größten Dateien/Ordner oder nur Ordner hinzufüge.
Antwort3
Das funktioniert bei mir:
#!/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
Der Hauptbefehl hier ist paste
, er verbindet die Ausgaben von ls
und du
horizontal.
du
gibt jede Zeile ungefähr so aus:
147291 ./.config
sed 's/\s.*//
löscht alles nach und einschließlich dem ersten Leerzeichen, d. h. ./.config
da wir an den nicht farbigen Formen der Namen der aufgelisteten Einträge nicht interessiert sind. Der Trick dabei ist, ls
den Inhalt des Verzeichnisses auf die gleiche Weise auszugeben wie, du
damit wir jeden Eintrag mühelos mit der entsprechenden Größe verbinden können. Das können wir mithilfe von -1
(das die Einträge vertikal statt horizontal auflistet), -U
(das die Einträge in Verzeichnisreihenfolge auflistet, genau wie du
, statt alphabetisch) und (das auch versteckte Verzeichnisse/Dateien auflistet, aber und im Gegensatz zu --almost-all
auslässt ) und natürlich . Für wird benötigt, damit sowohl Dateien (einschließlich versteckter) als auch Verzeichnisse statt nur Verzeichnisse verarbeitet werden und keine Unterverzeichnisse mehr bearbeitet (genau wie 's )..
..
--all
--color=always
du
--all
--max-depth=1
du
find
-maxdepth 1
Um die Frage zu beantworten, ist also nur Folgendes erforderlich:
paste <(du --all --max-depth=1 | sed 's/\s.*//') \
<(ls --color=always -1 --almost-all -U)
Was die anderen optionalen Argumente betrifft:
--apparent-size
drucktdu
scheinbare Größen, statt Festplattennutzung (meine Präferenz)--human-readable
druckt für Menschen lesbare Größen2>/dev/null
filtert allepermission denied
Fehler heraus, wenn Sie versucht haben,du
in einem eingeschränkten Verzeichnis zu laufen, zB/var
sort --human-numeric-sort
sortiert die Größen in absteigender Reihenfolge,--human-numeric-sort
wird benötigt, wenn--human-readable
andu
Antwort4
Durch die Kombination einiger der obigen Antworten mit oh-my-zshell auf einem Mac erhielt ich Größenangaben, farbige Verzeichnisnamen und Dateinamen im Klartext, die so sortiert waren, dass die 10 größten Dateien/Verzeichnisse ausgegeben wurden:
paste <(du -cks *) <(ls --color=always -1) | sort -nr | head | awk '{print $1 " " $3}'
Erklärung:
du
zur Datenträgernutzung -c:grand total -k: 1Kb blocks -s: entry
für jede Datei;
ls
zum Erfassen der Farbe für Verzeichnisse;
paste
zum Kombinieren der beiden obigen Ausgaben;
sort -nr
: numerische Rückwärtssortierung;
head
: gibt die größten Dateien/Verzeichnisse aus;
awk
: um nur die erste Spalte (Größe) und die 3. Spalte (Datei/farbiger Verzeichnisname) auszugeben