如何按类/指示器(如 ls --classify)然后按名称列出文件?

如何按类/指示器(如 ls --classify)然后按名称列出文件?

ls --clasify将指示符( 之一*/=>@|)附加到条目。我想将同一类别/指标的条目分组在一起。

我只能找到ls --group-directories-first将它们分组/在一起,如何对可执行文件*、符号链接@、管道|和套接字进行分组=

ls不是需要,欢迎任何肮脏的黑客。但至于输出样式,我想要一个带有指示器的多列彩色输出,类似于所做的ls -C --color -F

答案1

使用相同ls -CFUd穆鲁但在 中zsh,您可以尝试:

(set -o nullglob; ls --color -CFUd -- *(/) *(*) *(@) *(p) *(=) *(^/*@p=))

(...)在哪全局限定符匹配目录、可执行文件、符号链接、管道、套接字以及其他所有内容。

您还可以将bytype排序函数定义为:

zmodload -F zsh/stat b:zstat
bytype() {
  local mode order=(d l p s b c)
  zstat -sLA mode +mode -- $REPLY
  REPLY=$order[(ie)${mode[1][1]}]$REPLY
}
ls --color -CFUd -- *(o+bytype)

这将根据模式的文本表示的第一个字符(ls -l输出中的第一个字段)进行排序,因此-对于常规文件、l符号链接等,在数组中查找排名$order

请注意,可执行文件不是一种文件类型,因此不会对其进行特殊处理。对于ls -F、 或*glob 限定符,可执行文件是常规的其权限中至少设置了一个执行位的文件(无论是否你自己有执行权限),所以你可以用以下方式处理它们:

zmodload -F zsh/stat b:zstat
bytype() {
  local mode order=(d '*' l p s b c)
  zstat -sLA mode +mode -- $REPLY
  if [[ $mode = -*[xts]* ]] mode=('*')
  REPLY=$order[(ie)${mode[1][1]}]$REPLY
}

答案2

如果肮脏的黑客行为受到欢迎,那么以下内容可能会很接近:

ls -C --color -F -1 | rev | sort | rev

本质上:

  • rev首先获取最后一个字符
  • then sort,现在将首先使用最后一个字符
  • 然后rev再次取回原来的行

不幸的是,它有单列输出。您可以应用column它来获得多列输出,但由于非打印字符,列会变得混乱:

$ ls -C --color -F /proc/self/ -1 | rev | sort -i | rev | column -x
fd/     task/       fdinfo/ attr/   ns/     net/        cwd@
exe@        root@       sched           cmdline         oom_score       oom_score_adj       oom_adj
stack           syscall         mem         comm            statm           wchan           environ
mountinfo       io          pagemap         cgroup          autogroup       coredump_filter     clear_refs
maps            numa_maps       smaps           mountstats      limits          mounts          status
stat            schedstat       cpuset          auxv            personality

当然,它也有一些警告:

  • 文件名中没有换行符
  • ls文件名中没有任何标记字符

find一个 bash 函数,使用,sort和它本身的组合,ls结果很接近:

lsc () (
    [[ -z $1 ]] && set .
    for path
    do
        [[ -d $path ]] || { ls -CF --color "$path"; echo; continue; }
        (( $#  > 1 )) && printf '%s:\n' "$path" 
        find "$path" -maxdepth 1 -mindepth 1 ! -iname '.*' -printf "%y %p\0" |
        while IFS= read -d '' -r entry
        do
            ftype="${entry:0:1}"
            fname="${entry:2}"
            [[ $ftype == f && -x $fname ]] && ftype=x
            printf "$ftype $fname\0"
        done | sort -z -k1 | 
        sed -z 's/^. //; s:.*/::' |
        xargs -0 bash -c 'cd "$0"; ls -CFUd --color "$@"' "$path"
        (( $#  > 1 )) && echo
    done
)

通过使用ls它本身,打印到多列变得更加容易。

答案3

l='ls -F --color'  
paste -d: <($l | grep '/$') <($l | grep '*$') <($l | grep '@$') <($l | grep -v '[/@*]$') |
tac| column -t -s ":" -N FOLDERS,EXECUTABLES,LINKS,OTHER

在此输入图像描述

相关内容