for i in $(ls);do
if [ $i = '*.java' ];then
echo "I do something with the file $i"
fi
done
Quero fazer um loop em cada arquivo na pasta atual e verificar se ele corresponde a uma extensão específica. O código acima não funciona, sabe por quê?
for i in $(ls *.java); do echo "do something with file $i"; done
?$i
com a string literal "* .java"; a expansão do padrão não é executada aqui.if [[ $i == *.java ]]; then
.. (observe os double [[]] se não citados * .java).ls
- aceite a resposta de @chepnerRespostas:
Não são necessários truques sofisticados:
O guarda garante que, se não houver arquivos correspondentes, o loop será encerrado sem tentar processar um nome de arquivo inexistente
*.java
. Embash
(ou shells que suportam algo semelhante), você pode usar anullglob
opção de simplesmente ignorar uma correspondência com falha e não entrar no corpo do loop.fonte
for i in *.java *.cpp; do
. Se você tiver padrões estendidos habilitadosbash
comshopt -s extglob
, você pode escreverfor i in *.@(java|cpp); do
.shopt -s nullglob
para que um padrão não correspondente se expanda para a sequência vazia em vez de ser tratado literalmente.cd
for
nullglob
para que seja tratado como uma sequência vazia oufailglob
para que seja tratado como um erro. (Se você definir ambos,failglob
tem precedência.)a resposta correta é @chepner's
no entanto, aqui está um pequeno truque para verificar se um nome de arquivo tem uma determinada extensão:
fonte
ext
vez de.java
?Adicione subpastas recursivamente,
fonte
find . -name "*.java" -type f -exec echo \{\} \;
evitar a análise incorreta da saída defind
"$i"
dentro do loop.Loop através de todos os arquivos que terminam com:
.img
,.bin
,.txt
sufixo, e imprimir o nome do arquivo:Ou de forma recursiva (encontre também em todos os subdiretórios):
fonte
Concordo com as outras respostas sobre a maneira correta de percorrer os arquivos. No entanto, o OP perguntou:
Sim!
Um excelente artigo Qual é a diferença entre teste, [e [[?] Explica em detalhes que, entre outras diferenças, você não pode usar
expression matching
oupattern matching
dentro dotest
comando (que é uma abreviação de[
)Portanto, esta é a razão da falha do seu script. Se o OP estiver interessado em uma resposta com a
[[
sintaxe (que tem a desvantagem de não ser suportada em tantas plataformas quanto o[
comando), ficaria feliz em editar minha resposta para incluí-la.EDITAR: Quaisquer procedimentos sobre como formatar os dados na resposta como uma tabela seriam úteis!
fonte
como @chepner diz em seu comentário, você está comparando $ i a uma string fixa.
Para expandir e retificar a situação, você deve usar [[]] com o operador regex = ~
por exemplo:
a regex à direita de = ~ é testada em relação ao valor do operador do lado esquerdo e não deve ser colocada entre aspas (aspas não causam erro, mas são comparadas com uma string fixa e, portanto, provavelmente falharão "
mas a resposta de @chepner acima usando glob é um mecanismo muito mais eficiente.
fonte
ext
vez de.java
?if [[ $i == *.java ]]
ouif [[ $i == *.$ext ]]
. Mas não analise lsAchei essa solução bastante útil. Ele usa a
-or
opção emfind
:find . -name \*.tex -or -name "*.png" -or -name "*.pdf"
Ele vai encontrar os arquivos com a extensão
tex
,png
epdf
.fonte