Этот скрипт 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
Предупреждение: это будет плохо работать, когда есть файлы с пробелами... У меня нет лучшей идеи в данный момент.