Listar apenas arquivos regulares (mas não diretórios) no diretório atual

106

Eu posso usar ls -ld */ para listar todas as entradas de diretório no diretório atual. Existe uma maneira igualmente fácil de listar todos os arquivos regulares no diretório atual? Eu sei que posso usar o find

find . -maxdepth 1 -type f

ou stat

stat -c "%F %n" * | grep "regular file" | cut -d' ' -f 3-

mas isso não me parece excessivamente elegante. Existe um bom modo de listar apenas os arquivos regulares (não me importo com dispositivos, pipes etc.), mas não com os subdiretórios do diretório atual? Listar links simbólicos também seria uma vantagem, mas não é uma necessidade.

    
por daniel kullmann 18.09.2012 / 09:17

8 respostas

27

Com zsh e Qualificadores de Globos você pode expressá-los diretamente, por exemplo:

echo *(.)

retornará apenas a lista de arquivos regulares ou um erro, dependendo da sua configuração.

Para os não diretórios:

echo *(^/)

(incluirá links simbólicos (incluindo diretórios), pipes nomeados, dispositivos, soquetes, portas ...)

echo *(-.)

para arquivos regulares e links simbólicos para arquivos regulares.

echo *(-^/)

para não-diretórios e sem links simbólicos para diretórios.

Além disso, veja o qualificador D globbing se você quiser incluir arquivos D ot (arquivos ocultos), como *(D-.) .

    
por 18.09.2012 / 09:43
144
ls -p | grep -v / 

Este comando lista todos os arquivos não ocultos que não são diretórios (arquivos regulares, links, arquivos de dispositivos , etc. . Para também incluir arquivos ocultos, adicione a opção -A a ls

Ele pressupõe que nenhum dos arquivos tenha caracteres de nova linha em seus nomes. Adicionar uma opção -q a ls transformaria todos os caracteres não imprimíveis incluindo nova linha para ? , garantindo que eles estão em uma linha e adequados para alimentar um utilitário baseado em linha como grep e para impressão em um terminal.

    
por 23.02.2014 / 10:39
19

Para listar apenas arquivos regulares:

ls -al | grep '^-'

Com links simbólicos (para qualquer tipo de arquivo) incluídos:

ls -al | grep '^[-l]'

Onde o primeiro caractere da lista descreve o tipo de arquivo, então - significa que é um arquivo regular, pois o link simbólico é l .

Debian / Ubuntu

Imprima os nomes de todos os arquivos correspondentes (incluindo links):

run-parts --list --regex . .

com caminhos absolutos:

run-parts --list --regex . "$PWD"

Imprima os nomes de todos os arquivos em /etc que começam com p e terminam com d :

run-parts --list --regex '^p.*d$' /etc
    
por 04.03.2015 / 18:38
14

ls não tem opção para fazer isso, mas uma das coisas boas sobre o unix & linux é que pipelines longos e deselegantes podem ser facilmente transformados em um shell script, função ou alias. e estes, por sua vez, podem ser usados em pipelines como qualquer outro programa.

(NOTA: existem alguns problemas de escopo com funções e aliases. Scripts estão disponíveis para qualquer executável que possa lê-los e executá-los. Aliases e funções estão disponíveis apenas no shell atual - embora o .profile / .bashrc de um sub-shell etc pode redefini-los e, assim, torná-los disponíveis.Além disso, um script pode ser escrito em qualquer idioma - incluindo bash / sh, awk, perl, python e outros - o que for melhor para o trabalho ou com o qual você está mais familiarizado)

por exemplo,

alias lsf='find . -maxdepth 1 -type f -print0 | xargs -0r ls'

Eu adicionei xargs para que você possa usar todas as opções usuais de ls , por exemplo lsf -lrS

Como ele usa find , todos os dotfiles normalmente ocultos serão exibidos e todos os nomes de arquivos serão prefixados com ./ - essa é a única diferença que você notará.

Você pode excluir os arquivos de ponto com ! -iname '.*' , mas você precisa ter duas versões do alias - uma que exiba arquivos de pontos e outra que não tenha.

alias lsf2='find . -maxdepth 1 -type f -a ! -iname '\''.*'\'' -print0 | xargs -0r ls'

Como alternativa, se lsf fosse um script em vez de um alias, você poderia analisar as opções (talvez com getopts ou / usr / bin / getopt ou similar) e excluir dotfiles a menos que -a estivesse presente.

    
por 18.09.2012 / 10:11
7
bash-4.2$ ls -F | grep -v '[/@=|]$' | more

A opção -F para ls anexa * a executáveis, / a diretórios, @ a links simbólicos, = a soquetes e | para FIFOs. Você pode então usar o grep para excluir os caracteres de arquivo não regulares da saída e você tem os arquivos. Isso funcionará em qualquer shell, não apenas em zsh.

As fraquezas são:

  1. Qualquer arquivo cujo nome termine em @ , = ou | será excluído (mas você não deve ter arquivos com esses caracteres no nome)
  2. Isso não exclui arquivos de dispositivos ou alguns tipos exóticos de arquivos em alguns sistemas, como portas.
  3. Você terá um asterisco anexado em qualquer arquivo que seja executável. Isso poderia ser tratado por meio de canalização através do sed para remover qualquer caractere '*' da saída.
  4. Isso não funciona corretamente se houver nomes de arquivo contendo caracteres de nova linha.
por 07.10.2013 / 17:06
3

O manual declarou que a opção 'f' é apenas contra 'arquivo regular', não para pipes, soquete ou dispositivos de bloco / char, o que significa que você já está fazendo o que é certo.

   -type c
          File is of type c:

          b      block (buffered) special

          c      character (unbuffered) special

          d      directory

          p      named pipe (FIFO)

          f      regular file

          l      symbolic link; this is never true if the -L option or the
                 -follow option is in effect, unless the symbolic link  is
                 broken.  If you want to search for symbolic links when -L
                 is in effect, use -xtype.

          s      socket

          D      door (Solaris)
    
por 18.09.2012 / 09:34
0

Isso não é particularmente curto, mas você pode transformá-lo em um script ou alias, se precisar chamá-lo rapidamente. Usando o comando ls como uma matriz de entrada, chame ls -ld em cada entrada canalizada para o grep para excluir diretórios com a saída enviada para nulo e, se for bem-sucedida, repita a entrada original:

for list in 'ls' ; do ls -ld $list | grep -v ^d > /dev/null && echo $list ; done ;

Você pode inverter o grep e a saída condicional, os mesmos resultados:

for list in 'ls' ; do ls -ld $list | grep ^d > /dev/null || echo $list ; done ;
    
por 07.10.2013 / 11:05
0

Este é um tópico antigo, mas a maneira mais limpa de listar somente arquivos.

ls -al | grep '^-' | awk '{print $9}'
    
por 27.07.2018 / 23:10