1

У меня есть простой псевдоним, чтобы указать размер файлов и папок в cwd.

(включая точечные файлы в этом случае, игнорируя нулевые размеры)

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)

2 ответа2

1

Это то, что я придумал для 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 самых больших файлов / папок или папок.

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

Предупреждение: это будет плохо работать, когда есть файлы с пробелами... У меня нет лучшей идеи в данный момент.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .