Вы можете использовать опцию -F
команды lsof
, чтобы получить почти недвусмысленный вывод, который можно -анализировать с помощью машины лишь с умеренными трудностями . Вывод неоднозначен, потому что lsof
заменяет новые строки в именах файлов на \n
.
Выходные данные lsof
состоят из одного поля в строке. Первый символ каждого имени указывает тип поля, а остальная часть строки — значение поля. Поля:p
=PID (только для первого дескриптора в данном процессе ), f
=дескриптор, t
=тип(REG
для обычных файлов, единственный тип, который имеет размер ), s
= размер (только при наличии ), n
= имя. Приведенный ниже код awk собирает записи, имеющие размер, и печатает размер и имя файла. Остальные конвейеры сортируют выходные данные и сохраняют запись с наибольшим размером.
lsof -Fnst | awk '
{ field = substr($0,1,1); sub(/^./,""); }
field == "p" { pid = $0; }
field == "t" { if ($0 == "REG") size = 0; else next; }
field == "s" { size = $0; }
field == "n" && size != 0 { print size, $0; }
' | sort -k1n -u | tail -n42 | sed 's/^[0-9]* //'
Используйте zle -R
после push-input
для повторного отображения строки без буфера.
По большей части я считаю, что листинг завершения zsh устраняет необходимость в виджете для запуска ls. Он использует цвета в стиле ls и суффиксы типа файла -. У меня есть следующая привязка который выполняет завершение файла в любом контексте и делает длинный список в стиле ls -l
:
zstyle ":completion:file-complete::::" completer _files
zle -C file-complete complete-word _generic
zstyle ':completion:file-complete:*' file-list true
bindkey '^X^F' file-complete
Благодаря вкладу @okapi я придумал это.
function myls {
[[ "$CONTEXT" = cont ]] && return
zle push-input
zle -R
zle accept-line
print -n $(ls --color=always --indicator-style=slash)
}
zle -N myls
bindkey -- '^[l' myls
Это намного лучше, но не работало с продолжением, как в циклах 'for>...' и 'while>...', так что я пока просто возвращаю в них.