Estou tentando encontrar todos os arquivos com uma extensão específica em um diretório e seus subdiretórios com o meu bash (versão mais recente do Ubuntu LTS).
Isto é o que está escrito em um arquivo de script:
#!/bin/bash
directory="/home/flip/Desktop"
suffix="in"
browsefolders ()
for i in "$1"/*;
do
echo "dir :$directory"
echo "filename: $i"
# echo ${i#*.}
extension=`echo "$i" | cut -d'.' -f2`
echo "Erweiterung $extension"
if [ -f "$i" ]; then
if [ $extension == $suffix ]; then
echo "$i ends with $in"
else
echo "$i does NOT end with $in"
fi
elif [ -d "$i" ]; then
browsefolders "$i"
fi
done
}
browsefolders "$directory"
Infelizmente, quando inicio esse script no terminal, ele diz:
[: 29: in: unexpected operator
(com em $extension
vez de 'in'
)
O que está acontecendo aqui, onde está o erro? Mas esse aparelho encaracolado
Respostas:
é um pouco mais curto que tudo isso (e mais seguro - lida com espaço em branco em nomes de arquivos e nomes de diretórios).
Provavelmente, seu script está falhando nas entradas que não têm um
.
no nome, tornando-as$extension
vazias.fonte
find
é recursivo por padrão. você pode limitar as profundidades, se quiser (consulte a página de manual).Exemplo: Para encontrar todos os
csv
arquivos no diretório atual e seus subdiretórios, use:fonte
A sintaxe que eu uso é um pouco diferente do que o @Matt sugeriu:
(é apenas um toque de tecla).
fonte
Sem usar
find
:fonte
grep
não é realmente necessário aqui.awk
possui expressões regulares e pode limitar sua saída a valores correspondentes a um padrão.awk|grep
é um anti-padrão. Deixe o awk fazer o grepping.{
falta depoisbrowsefolders ()
$in
devem ser$suffix
cut
você recebe apenas a parte do meio defront.middle.extension
. Você deve ler o manual do shell${varname%%pattern}
e os amigos.Suponho que você faça isso como um exercício de script de shell, caso contrário, a
find
solução já proposta é o caminho a seguir.Para verificar a sintaxe apropriada do shell, sem executar um script, use
sh -n scriptname
.fonte
fonte
Embora o uso do
find
comando possa ser útil aqui, o próprio shell fornece opções para atingir esse requisito sem ferramentas de terceiros. Obash
shell fornece uma opção estendida de suporte global, com a qual você pode obter os nomes dos arquivos em caminhos recursivos que correspondem às extensões desejadas.A opção estendida é a
extglob
que precisa ser definida usando ashopt
opção abaixo. As opções são ativadas com o-s
suporte e desativadas com o-u
sinalizador. Além disso, você pode usar mais algumas opções, ou seja,nullglob
nas quais um globo incomparável é varrido completamente, substituído por um conjunto de zero palavras. Eglobstar
isso permite recuperar através de todos os diretóriosAgora, tudo o que você precisa fazer é formar a expressão glob para incluir os arquivos de uma determinada extensão, que você pode fazer como abaixo. Usamos uma matriz para preencher os resultados globais porque, quando citados corretamente e expandidos, os nomes de arquivos com caracteres especiais permaneceriam intactos e não seriam quebrados devido à divisão de palavras pelo shell.
Por exemplo, para listar todos os
*.csv
arquivos nos caminhos recursivosA opção
**
é recursar pelas subpastas e*.csv
é uma expansão global para incluir qualquer arquivo das extensões mencionadas. Agora, para imprimir os arquivos reais, bastaUsar uma matriz e fazer uma expansão entre aspas adequada é o caminho certo quando usado em scripts de shell, mas para uso interativo, você pode simplesmente usar
ls
com a expressão glob comoIsso pode muito bem ser expandido para corresponder a vários arquivos, ou seja, arquivo que termina com várias extensões (ou seja, semelhante à adição de vários sinalizadores no
find
comando). Por exemplo, considere um caso de necessidade de obter todos os arquivos de imagem recursivos, ou seja, de extensões*.gif
,*.png
e*.jpg
tudo o que você precisa éIsso poderia muito bem ser expandido para ter resultados negativos. Com a mesma sintaxe, pode-se usar os resultados da glob para excluir arquivos de determinado tipo. Suponha que você deseja excluir nomes de arquivos com as extensões acima, você pode fazer
A construção
!()
é uma operação de negação para não incluir nenhuma das extensões de arquivo listadas dentro e|
é um operador de alternância da mesma forma que é usado na biblioteca Extended Regular Expressions para fazer uma correspondência OR dos globs.Observe que esse suporte estendido a glob não está disponível no shell POSIX bourne e é puramente específico para as versões recentes do
bash
. Portanto, se você está considerando a portabilidade dos scripts executados no POSIX e nosbash
shells, essa opção não está correta.fonte
Para encontrar todos os
pom.xml
arquivos em seu diretório atual e imprimi-los, você pode usar:fonte
fonte
fonte