Bash: ls * sem agrupamento de pastas


12

Se eu digitar:

ls source/*

source/fonts:
fontello

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

Eu recebo 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   

Obrigado


Se for para uso de script, convém ver mywiki.wooledge.org/ParsingLs . (Dito isto, existem maneiras de usar finderrado também; particularmente, se você estiver correndo for file in $(find ...), você acertou um deles).
Charles Duffy

Respostas:


13

Parece não ser possível sem alteração na saída, mas aqui está uma maneira alternativa fácil:

find source/ -type f

Ou (específico para a localização do GNU), para obter apenas arquivos detalhados na sua pergunta:

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

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


5

Você pode simplesmente manter 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

@Cthulhu ok, meu exemplo é muito curto. Se você tiver pastas em A, B / C, o -d ajuda a exibir apenas o que você selecionou. Na verdade, eu não gosto de encontrar e você pode definir a profundidade pelo argumento com ls -d
ikrabbe

Sugeri uma edição para a outra resposta para limitar a profundidade.
o11c 18/06/2015

@ o11c muito bom, mas ainda findé um animal gordo.
ikrabbe

3

Você pode estar interessado em "o pobre homem find":

shopt -s globstar

shopt -s s ETS a opção shell nomeado (s). A globstaropção é definida da seguinte forma no bash (1) :

Se definido, o padrão **usado em um contexto de expansão de nome de arquivo / nome de caminho corresponderá a um arquivo [sic] e a zero ou mais diretórios e subdiretórios. Se o padrão for seguido por a /, apenas diretórios e subdiretórios corresponderão.

Então, depois de concluir shopt -s globstar, qualquer um dos seguintes comandos:

ls -d1 - source / **                  # O caractere após o 'd' é o dígito. 
ls -d - fonte / ** | cat             # ou seja, ele escreverá isso em um pipe para qualquer comando. 
printf "% s \ n" fonte / **

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 também os nomes dos diretórios. Talvez ajude um pouco a saber que

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

produzirá a saída:

source/
source/fonts
source/images

ou seja, apenas os nomes de diretório. Você pode redirecionar a saída de um dos primeiros conjuntos de comandos para um arquivo, redirecionar a saída dos itens acima para um segundo arquivo e, em seguida comm, usar diff, ou algo semelhante, para subtrair o segundo arquivo do primeiro, deixando apenas a planície arquivos (não diretórios). Mas não faça isso.

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

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

A --file-typeopção diz lspara exibir um / no final de cada nome de diretório (e outros caracteres no final de outros tipos de arquivos (especiais)), assim:

source //                             # Adicionado um extra 
source / fonts /                        # Adicionado um
fonte / fontes / fontello
source / images /                       # Adicionado um
source / images / bg1.png
source / images / eng.png
source / images / fra.png

e então grep -v '/$'remove as linhas que terminam com /; ou seja, os nomes dos diretórios. Infelizmente, a --file-typeopção não é especificada pelo POSIX . Se a sua versão do lsnão suportar, use -F. É assim, --file-type exceto que também exibe um *no final dos nomes dos arquivos executáveis, o que algumas pessoas consideram irritante. Você pode eliminá-los com sed:

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

Se você quiser fazer algo com todos os arquivos (e apenas os arquivos), poderá fazer

para f na fonte / **
Faz
    se [-f "$ f"]
    então
        Insira comandos a serem aplicados aos arquivos simples aqui.
    fi
feito

Notas:

  • Quando lsé saída para um terminal, e não é em -l( l modo ong), escreve vários nomes por linha (a menos que os nomes são muito longos). Você pode forçá-lo a escrever um nome por linha especificando -1(um) ou redirecionando a saída para um arquivo ou canal.
  • Você provavelmente não precisa realmente --dos lscomandos, pois está listando um diretório cujo conteúdo foi criado. Você deve usá-lo ao listar *em um diretório desconhecido, como proteção contra nomes de arquivos que começam com -.
  • Não tente analisar a saída de ls.
  • A globstaropção shell parece não estar definida pelo POSIX. (Na verdade, não tenho certeza se o POSIX reconhece nenhuma opção de shell.) Embora pareça um bashismo, tenha cuidado - ele pode não estar presente em todas as versões do bash.
  • Se fontsou imagestiver subdiretórios, **os listará todos, recursivamente, até o fim. Uma maneira (um tanto arrogante e não confiável) de limitar a profundidade é

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

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

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.