Como testar corretamente a extensão do arquivo na instrução if?

3

Apenas uma ilustração:

primeiro

cd /usr/lib

e execute

for x in $(ls);do if [ "$x" == "*.a" ];then echo $x;fi;done

O que eu quero fazer é selecionar arquivos com extensão .a e imprimi-los. Eu sei que há uma maneira muito mais simples de fazer isso, mas essa não é minha intenção aqui.

O problema é que o comando acima não funciona. Eu não sei porque. Eu aprendo isso com esta postagem

Eu também tentei

[ "$x" == *.a ]    bash: [: too many arguments
[ $x = "*.a" ]    shows nothing
[ $x = *.a ]    bash: [: too many arguments

Eu sei que [[ $x == *.a ]] funciona, mas eu quero saber qual é a maneira correta de escrever [ teste neste caso?

    
por user15964 09.03.2017 / 15:47

2 respostas

4
for x in ./*; do
   case $x in
      *".a" ) echo "$x";;
   esac
done

A construção [ não é exatamente adequada para isso. Mas se você insistir, podemos fazer da seguinte forma:

[ '.a'  =  ".${x##*.}" ]

Explicação

Digamos $ x contém: my.file.testing.a Então ${x##*.} , a partir da esquerda, removerá o máximo possível até o último . que conseguir ver em $x . IOW, acabamos largando tudo e trazendo a extension viz, a para o primeiro plano. Então agora temos a extensão que acabamos de computar para comparar com o que achamos melhor ( .a ) para o sucesso.

    
por 09.03.2017 / 16:06
1

A resposta a que você se vinculou em sua pergunta usa a sintaxe de teste estendido de do bash , enquanto você está tentando usar o operador de teste de colchete único POSIX. A diferença é que, no teste de duplo-colchete, o lado direito de um == é tratado como um padrão, em vez de estar sujeito à divisão de palavras ou à expansão glob. Então, enquanto [ $f == *.a ] resulta no erro [: too many arguments , você pode fazer

for f in *; do if [[ $f == *.a ]]; then echo "$f"; fi; done

ou (mais compactamente)

for f in *; do [[ $f == *.a ]] && echo "$f"; done

Como alternativa, como você parece estar usando bash , você pode usar o operador de expressão regular =~ , por exemplo,

for f in *; do if [[ $f =~ \.a$ ]]; then echo "$f"; fi; done

ou (mais compactamente)

for f in *; do [[ $f =~ \.a$ ]] && echo "$f"; done

embora seja exagero nesse caso.

    
por 09.03.2017 / 17:39

Tags