Bash: ls * sem agrupamento de pastas

12

Se eu digitar:

ls source/*

source/fonts:
fontello

source/images:
bg1.png                eng.png        fra.png   

Eu obtenho a lista de arquivos, agrupados por nomes de pastas. Como posso simplesmente obter a lista de nomes de arquivos?

ls source/*

source/fonts/fontello
source/images/bg1.png
source/images/eng.png
source/images/fra.png   

Obrigações

    
por Augustin Riedinger 18.06.2015 / 12:04

3 respostas

13

Não parece ser possível sem alteração de saída, mas aqui está uma maneira alternativa fácil:

find source/ -type f

Ou (específico para encontrar o GNU), para obter apenas arquivos detalhados em sua pergunta:

find source/ -type f -mindepth 2 -maxdepth 2

(ou se você quiser diretórios como ls , remova -type f )

    
por 18.06.2015 / 12:21
5

Você pode simplesmente colar em ls se adicionar alguns psicodélicos ( ls -d ):

# mkdir test
# cd test
# mkdir A B C
# touch {A,B,C}/file*
# ls -d */*    
A/file  B/file  C/file
    
por 18.06.2015 / 14:41
3

Você pode estar interessado em "co_de% do pobre":

shopt -s globstar

find s define as opções de shell nomeadas. A opção shopt -s é definida da seguinte forma em bash (1) :

If set, the pattern ** used in a filename/pathname expansion context will match a files [sic] and zero or more directories and subdirectories.  If the pattern is followed by a /, only directories and subdirectories match.

Então, depois de ter feito globstar , qualquer um dos seguintes comandos:

ls -d1 -- source/**                 # The character after the ‘d’ is the digit one.
ls -d -- source/** | cat            # i.e., it will write that into a pipe to any command.
printf "%s\n" source/**

produzirá a saída:

source/
source/fonts
source/fonts/fontello
source/images
source/images/bg1.png
source/images/eng.png
source/images/fra.png

Infelizmente, isso inclui os nomes dos diretórios também. Pode ajudá-lo um pouco a saber que

printf "%s\n" source/**/

produzirá a saída:

source/
source/fonts
source/images

isto é, somente os nomes dos diretórios. Você pode redirecionar a saída de um dos primeiros conjuntos de comandos para um arquivo, redirecionar a saída do acima para um segundo arquivo, e, em seguida, use shopt -s globstar , comm ou algo semelhante, para subtrair o segundo arquivo do primeiro, deixando apenas os arquivos simples (não-diretórios). Mas o não faz isso.

Outra abordagem (que não é muito melhor) é

ls -d --file-type -- source/** | grep -v '/$'

A opção diff informa --file-type para exibir um ls no final de cada nome de diretório (e outros personagens nas extremidades de outros tipos de arquivos (especiais)), assim:

source//                            # Added an extra one
source/fonts/                       # Added one
source/fonts/fontello
source/images/                      # Added one
source/images/bg1.png
source/images/eng.png
source/images/fra.png

e, em seguida, o / remove as linhas que terminam com grep -v '/$' ; isto é, os nomes dos diretórios. Infelizmente, a opção / não é especificada por POSIX . Se sua versão de --file-type não oferecer suporte, use ls . Isso é como -F exceto que também exibe um --file-type nas extremidades dos nomes dos arquivos executáveis, que algumas pessoas acham chato. Você pode eliminá-los com * :

ls -dF -- source/** | sed -e '/\/$/d' -e 's/\*$//'

Se você quiser fazer algo com todos os arquivos (e somente os arquivos), você pode fazer

for f in source/**
do
    if [ -f "$f" ]
    then
        Insert commands to be applied to plain files here.
    fi
done

Notas:

  • Quando sed está saindo para um terminal e não está no modo ls ( l ong), ele grava vários nomes por linha (a menos que os nomes sejam muito longos). Você pode forçá-lo a escrever um nome por linha, especificando -l (um), ou redirecionando a saída para um arquivo ou um canal.
  • Você provavelmente não precisa dos -1 nos comandos -- desde que você esteja listando um diretório cujo conteúdo você criou. Você deve usá-lo ao listar ls em um diretório desconhecido como proteção contra nomes de arquivos que começam com * .
  • Não tente analisar a saída de - .
  • A opção ls shell parece não ser definida pelo POSIX. (Na verdade, não tenho certeza se o POSIX reconhece qualquer opção de shell.) Embora pareça ser um globstar ism, cuidado - pode não estar presente em todas as versões do bash.
  • Se bash ou fonts tiver subdiretórios, images listará todos eles, recursivamente, todo o caminho. Uma maneira (um pouco desajeitada e pouco confiável) de limitar a profundidade é

    ls -d --file-type -- source/** | grep -v '\(/.*\)\{3\}'
    

    que remove linhas contendo três ou mais caracteres ** .

por 20.06.2015 / 06:32

Tags