让 ls 命令根据条目数有不同的行为

让 ls 命令根据条目数有不同的行为

是否可以根据可能列出的目录条目数使 ls 命令表现不同?

如果我只是使用ls(没有修改选项,但我可以指定目录或过滤器),我希望它:

  • -l如果条目数或少于 10 条,则采用长列表格式
  • 仅显示前 50 个条目并输出警告x more entries

这可能吗?我怎样才能做到这一点?

请注意,我不想使用自定义脚本命令切换到自定义命令 - 我可以使用自定义脚本或包装器,但我仍然想使用ls它来执行此操作,并且仍保留完整功能。也就是说,不仅仅是my-custom-ls调用ls脚本/包装器。

答案1

如果您不需要自定义脚本命令/包装函数,那么您需要自定义二进制命令。 GNUls源代码以及其他实现都可用。

创建您自己的修补版本,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
}

答案2

创建您自己的脚本(例如,在 Python 中),该脚本计算参数并ls(1)使用正确的参数进行调用,并more(1)根据需要进行分页(如果输出转到 tty)。

答案3

我无法重新定义 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 字数统计函数)来计算有多少个。您可以更改“10”比较中的文件数量。您可以通过更改ls -l和/或ls -a命令来更改实际执行的操作

如果您不熟悉 bash 函数 - 将代码放入文件中,然后chmod +x将该文件使其可执行,然后运行该文件,. the_filename然后使用该函数ls2

对于永久解决方案,将该函数添加到您的.bashrc文件中(并考虑创建一个源自.bashrc该文件的文件,以便您可以开始在一个位置添加更多函数,而不会让您的.bashrc文件变得笨拙。

我不能一次少地显示条目。

答案4

这是我对这个问题的解释。它是 bash 特定的,因为它使用数组。它定义了一个名为的函数ls(因此请务必运行unalias ls以清除其执行的方式ls)。该函数创建给定参数的数组(如果没有给出参数,则创建当前目录内容的数组);然后它对这些元素进行计数以确定ls要使用哪些标志(小于 10,则使用ls -ld;否则使用ls -d);如果文件超过 50 个,则仅显示前 50 个,并显示一条消息。我还厚颜无耻地复制了 Kevin/jlliagre 的想法,让函数ls在输出不输出到屏幕时表现得更正常。

这不允许将标志传递给 real 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
}

相关内容