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 **
.