Попросите команду ls вести себя по-разному в зависимости от количества записей

Возможно ли, что команда ls ведет себя по-разному в зависимости от количества записей в каталоге, которые могут быть перечислены?

Если я просто использую ls (без модификаций, но я могу указать каталоги или фильтры), я хочу:

  • применять -l длинный формат списка, если есть 10 записей или меньше
  • показывать только первые 50 записей и выводить предупреждение о наличии еще x more entries

Это возможно? Как я могу это сделать?

Обратите внимание, что я не хочу использовать собственный скрипт командной строки для командной строки – я в порядке с пользовательским скриптом или оболочкой, но я все же хочу использовать ls для этого, при этом все функции сохраняются. То есть, не my-custom-ls а просто ls чтобы вызвать скрипт / обертку.

Если вам не нужна специальная функция / команда-сценарий скрипта, вам нужна пользовательская двоичная команда. Исходный код GNU ls доступен вместе с другими реализациями.

Создайте свою собственную исправленную версию ls и вы будете установлены.

Обратите внимание, что это изменение в поведении приведет к нарушению соответствия POSIX.

Изменить (согласно вашему пересмотренному вопросу):

 ls() { if [ $(command ls "$@" | wc -l) -gt 10 ]; then command ls "$@" | head -50 else command ls -l "$@" fi } 

Расширенная версия, показывающая количество оставшихся записей:

 ls() { [ ! -t 1 ] && { command ls "$@" ; return ; } r=$(command ls "$@") lines=$(printf "%s" "$r" | wc -l) if [ $lines -gt 10 ]; then printf "%s" "$r" | head -50 if [ $lines -gt 50 ]; then printf "%d more entries\n" $((lines - 50)) fi else command ls -l "$@" fi } 

Создайте свой собственный скрипт, например, в Python, который подсчитывает аргументы и вызывает ls(1) с правильными аргументами и выравнивает его с more(1) для подкачки по мере необходимости (если вывод идет в tty).

Я не могу переопределить сам ls, но вы можете использовать эту функцию для 'ls2':

 ls2 () { num_of_files=`ls | grep "\/$" | wc -l` if [ "$num_of_files" -gt "10" ]; then ls | less else ls -l fi } 

для создания пользовательской команды ls2, которая использует grep для поиска каталогов, а затем wc (unix word count function with number of lines), чтобы подсчитать, сколько. Вы можете изменить количество файлов в сравнении «10». Вы можете изменить то, что на самом деле сделано, изменив команды ls -l и / или ls -a

Если вы не знакомы с функциями bash – поместите код в файл, затем chmod +x файл, чтобы сделать его исполняемым, а затем запустите файл . the_filename . the_filename а затем использовать функцию с ls2

Для постоянного решения добавьте функцию в ваш .bashrc файл (и подумайте о создании файла, который получен из .bashrc , чтобы вы могли начать добавлять больше функций в одно место и не делать ваш .bashrc файл неуклюжим.

Я не могу получить меньше, чтобы показывать записи за раз.

Одна вещь, которую вы можете сделать, – это разместить каждый листинг на отдельной строке, а затем использовать wordcount для подсчета строк и иметь оператор if else if в зависимости от количества файлов.

 files=$(ls "$@" | wc -l) if [ $files -ge 50 ] then something fi 

извините, если это не то, что вы ищете.

Вот моя интерпретация вопроса. Это зависит от bash, так как он использует массив. Он определяет функцию с именем ls (поэтому обязательно запустите unalias ls чтобы очистить способ ее выполнения как только ls ). Функция создает массив данных аргументов (или текущего содержимого каталога, если аргументы не заданы); Затем он подсчитывает эти элементы, чтобы определить, какие флаги ls использовать (менее 10, использовать ls -ld , иначе использовать ls -d ); если файлов более 50, отображаются только первые 50, и отображается сообщение. Я также нагло копировал идею от Kevin / jlliagre, чтобы функция ls вела себя более нормально, когда выход не является экраном.

Это не позволяет передавать флаги реальным ls ; такие вещи, как -r и -a , нуждаются в особой заботе.

 function ls { _ls_longlimit=10 _ls_cutoff=50 declare -a _ls_files [ ! -t 1 ] && { command ls "$@"; return; } # TODO: skip past any "-rtxyz" options if [ $# -eq 0 ] then _ls_files=(*) else for a in "$@" do if [ -d "$a" ] then # add "${a}/*" to array _ls_files+=("${a}"/*) else # add $a to array _ls_files+=("$a") fi done fi if [ ${#_ls_files[@]} -le $_ls_longlimit ] then command ls -ld "${_ls_files[@]}" else # -1 because arrays are 0-based command ls -d "${_ls_files[@]:0:_ls_cutoff - 1}" fi if [ ${#_ls_files[@]} -gt $_ls_cutoff ] then echo $((${#_ls_files[@]} - _ls_cutoff)) more entries fi }