usando 'for file in' para selecionar vários nomes de extensão e, em seguida, obter o nome de base de "file", em seguida, concatenar um nome de extensão

1

Eu estou tentando praticar minhas habilidades unix, eu acabei de aprender como usar for file in *.jpg; o que ele faz é selecionar todos os arquivos com .jpg no diretório de trabalho, mas eu não quero parar por aí e eu não quero para executar meu script bash duas vezes

Então aqui está o cenário, eu tenho esses arquivos, e eu desejo é selecionar cada um deles, em seguida, substituir o nome da extensão para outro e espero que o processo seja algo como basename + ".done", então test1.jpg se torna test1.done

test1.jpg
test2.jpeg
test3.txt
test4.dummy

Agora, o que eu quero é de alguma forma, colocar esses nomes de extensão .jpg,.jpeg,.txt,.dummy em uma matriz, então usar isso em for loop algo como for file in *{.jpg,.jpeg,.txt,.dummy}; do , mas eu tentei e não funciona, o shell parece não permitir matrizes em loop?

alguém pode me ajudar e me dar um exemplo de como resolver isso? obrigado!

UPDATE

então, aprendi que usar for file in *.{jpg,jpeg,test} resolverá meu problema, mas às vezes falha, especialmente quando não há arquivo com uma extensão declarada na matriz

Exemplo:

test1.jpg
test2.jpeg
test3.test
test4.dummy

Usando um bash como:

for file in *.{jpg,jpeg,test,avi}; do size=$(stat -c '%s' "$file"); echo $file filesize is: $size; done

vai acabar feio:

test1.jpg filesize is: 2
test2.jpeg filesize is: 0
test3.test filesize is: 0
stat: cannot stat '*.avi': No such file or directory
*.avi filesize is:

as últimas 2 linhas acima são desnecessárias, desejo que exista algo como break , em que se for não encontrar avi , pare a do

Isso é possível?

    
por The Wolf 15.04.2015 / 12:08

1 resposta

2

Se você estiver usando bash , poderá definir a opção nullglob :

  nullglob
    If set, bash allows patterns which match no  files  (see
    Pathname  Expansion  above)  to expand to a null string,
    rather than themselves.

Para ilustrar:

$ ls
test1.dummy  test1.jpeg  test1.jpg  test1.test
$ shopt nullglob
nullglob        off
$ for file in *.{jpg,jpeg,test,avi}; do 
    echo "$file size is $(stat -c '%s' "$file")"; 
  done
test1.jpg size is 0
test1.jpeg size is 0
test1.test size is 0
stat: cannot stat ‘*.avi’: No such file or directory
*.avi size is 

E se ativarmos nullglob :

$ shopt -s nullglob 
$ shopt nullglob ## just to demonstrate that it is on
nullglob        on
$ for file in *.{jpg,jpeg,test,avi}; do      
    echo "$file size is $(stat -c '%s' "$file")"
 done
test1.jpg size is 0
test1.jpeg size is 0
test1.test size is 0

Como alternativa, você pode ter certeza de que o arquivo existe (também estou usando este exemplo para demonstrar que a expansão de chave não é necessária aqui):

$ for file in *jpg *jpeg *test *avi; do
    [ -e "$file" ] &&  echo "$file size is $(stat -c '%s' "$file")" 
  done
test1.jpg size is 0
test1.jpeg size is 0
test1.test size is 0
    
por 15.04.2015 / 13:01

Tags