У меня есть простой псевдоним для вывода размера файлов и папок в cwd.
(включая dotfiles в этом случае, игнорируя нулевые размеры)
du -sh .[!.]* * | sort -hr | grep -v '^0'
что также может быть достигнуто с помощью find:
find .[!.]* * -maxdepth 0 -exec du -sh {} \; | sort -hr | grep -v '^0'
пример вывода:
// .ssh & .byobu are folders - .zsh* are files
// currently not able to distinguish them by type
...
32K .zshrc
25K .ssh
20K .zcompdump
19K .byobu
...
Как раскрасить файлы/каталоги в выводе в соответствии с цветами ls?( LS_COLORS )
решение1
Этот zsh
скрипт анализирует $LS_COLORS
. Ему нужен только stat
вызов для каждого файла, и поэтому он намного быстрее, чем решение внизу, которое вызывает ls
каждый файл. И он правильно обрабатывает файлы с пробелами. ( \n
или\t
все ещенетразрешено в именах файлов)
Однако реализация не завершена. Я включил цвета только для разных типов файлов, которые можно определить по первому символу строки режима файла (например, lrwxrwxrwx
для символической ссылки) или по расширению файла. Это означает, что разрешения на запись для всех, suid или sticky биты не окрашены специально. Включить их также должно быть просто.
source
следующее и используйте новую функцию оболочки duc
для цветного du
вывода:
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
}
}
Это мой старый скрипт, тоже для . Он, вероятно, излишне сложен и очень медленный, так как для каждого файла выдается zsh
одна команда:ls
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))]}
}
}
- в
.*
волеzsh
нетсоответствует.
или..
, но файлы, подобные..foo
которым, будут пропущены с.[!.]*
typeset -a
объявляет массив- циклы for для массива,
$i
принимают значения от 1 и далее с шагом 2
Предупреждение: Это приведет к серьезным сбоям, если есть файлы спробелы... На данный момент у меня нет лучшей идеи.
решение2
Вот что я придумал для bash — использует pv для отображения прогресса вывода
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
}
Теперь скрипт можно превратить в однострочный... но я улучшу функцию, добавив флаги, например, для 10 самых больших файлов/папок или только для папок.
решение3
Мне это подходит:
#!/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
Основная команда здесь — paste
, она объединит выходы ls
и du
по горизонтали.
du
выведет каждую строку примерно так:
147291 ./.config
sed 's/\s.*//
удалит все после и включая первый пробел, т.е. ./.config
поскольку нас не интересуют неокрашенные формы имен перечисленных записей. Хитрость здесь в том, чтобы сделать ls
вывод содержимого каталога таким же образом, как du
и так, чтобы мы могли без усилий объединить каждую запись с ее соответствующим размером. Мы можем сделать это с помощью -1
(который перечисляет записи вертикально, а не горизонтально), -U
(который перечисляет записи в порядке каталога, как du
, а не в алфавитном порядке) и --almost-all
(который перечисляет скрытые каталоги/файлы, но исключает .
и ..
в отличие от --all
) и, конечно же --color=always
. Для du
, --all
необходимо заставить его обрабатывать как файлы (включая скрытые), так и каталоги, а не только каталоги, и --max-depth=1
прекратить du
работу с подкаталогами (как find
's -maxdepth 1
)
Итак, чтобы ответить на вопрос, необходимо лишь следующее:
paste <(du --all --max-depth=1 | sed 's/\s.*//') \
<(ls --color=always -1 --almost-all -U)
Что касается других необязательных аргументов:
--apparent-size
делаетdu
печать видимых размеров, а не использования диска (мое предпочтение)--human-readable
печатает размеры, удобные для восприятия человеком2>/dev/null
отфильтровывает любыеpermission denied
ошибки, если вы попытались запуститьdu
в ограниченном каталоге, например/var
sort --human-numeric-sort
сортирует размеры в порядке убывания,--human-numeric-sort
необходимо, если--human-readable
передаетсяdu
решение4
Объединение некоторых из приведенных выше ответов с oh-my-zshell на Mac дало мне размеры, цветные имена каталогов и имена файлов в виде обычного текста, отсортированные для вывода 10 самых больших файлов/каталогов:
paste <(du -cks *) <(ls --color=always -1) | sort -nr | head | awk '{print $1 " " $3}'
Пояснение:
du
для использования на диске -c:grand total -k: 1Kb blocks -s: entry
для каждого файла;
ls
для захвата цвета для каталогов;
paste
для объединения обоих вышеуказанных выходных данных;
sort -nr
: числовая обратная сортировка;
head
: выводит самые большие файлы/каталоги;
awk
: выводит только первый столбец (размер) и 3-й столбец (имя файла/раскрашенного каталога)