Como posso listar arquivos por classe / indicador (como em ls --classify) e por nome?

2

ls --clasify indicador de acréscimo (um de */=>@| ) às entradas. Gostaria de agrupar as entradas da mesma classe / indicador juntos.

Só consigo encontrar ls --group-directories-first para agrupar o / , como posso agrupar executáveis * , links simbólicos @ , pipes | e sockets = , também?

ls é não obrigatório, qualquer invasão de sujeira é bem-vinda. Mas quanto ao estilo de saída, eu gostaria de uma saída colorida com várias colunas com um indicador, semelhante ao que o ls -C --color -F fez.

    
por Giumo 09.08.2015 / 05:37

2 respostas

1

Se hacks sujos forem bem-vindos, os seguintes itens podem se aproximar:

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

Essencialmente:

  • rev para obter o último caractere primeiro
  • , em seguida, sort , que agora usará o último caractere primeiro
  • , em seguida, rev novamente para recuperar a linha original

Isso, infelizmente, tem saída de coluna única. Você pode aplicar column a ele para obter uma saída com várias colunas, mas, devido aos caracteres não imprimíveis, as colunas ficam confusas:

$ 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

E, claro, isso exige ressalvas:

  • sem novas linhas nos nomes de arquivos
  • nenhum dos caracteres de marcação ls está nos nomes de arquivo

Uma função bash, usando uma combinação de find , sort e ls em si que chega perto:

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
ls -C --color -F -1 | rev | sort | rev
" | while IFS= read -d '' -r entry do ftype="${entry:0:1}" fname="${entry:2}" [[ $ftype == f && -x $fname ]] && ftype=x printf "$ftype $fname
$ 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
" done | sort -z -k1 | sed -z 's/^. //; s:.*/::' | xargs -0 bash -c 'cd "$0"; ls -CFUd --color "$@"' "$path" (( $# > 1 )) && echo done )

Usando ls , a impressão em várias colunas se torna muito mais fácil.

    
por 09.08.2015 / 07:15
1

Usando o mesmo ls -CFUd como muru , mas em zsh , você poderia tentar com:

setopt nullglob
ls --color -CFUd -- *(/) *(*) *(@) *(p) *(=) *(^/*@p=)

em que (...) são glob-qualifiers diretórios, executáveis, links simbólicos, canos, tomadas e, respectivamente, todo o resto.

    
por 09.08.2015 / 22:04