O caractere curinga não está sendo interpretado na instrução if

2

Atualmente, estou escrevendo o script abaixo. O código examina um determinado diretório para um nome de arquivo inserido pelo usuário. O script primeiro verifica se o arquivo de entrada é um gzip, se assim for, ele executa as verificações correspondentes. Se o arquivo não for compactado, ele responderá com um texto de arquivo incompatível.

O problema que estou encontrando está na linha 7 . Não importa a extensão do arquivo, estou recebendo um arquivo incompatível como resultado final.

#!/bin/bash
DATE=$(date +%Y-%m-%d)
L0_Report_Generator=("/home/ubuntu/$gzip_file")
echo -n "Enter File Directory:"$gzip_file 
read  $gzip_file
for gzip_file in {$L0_Report_Generator}; do
  if [[ $gzip_file = "test_sub"*"gz" ]] #Check file extension for gzip compression
      then
         gunzip $gzip_file
         echo "file Level 0 QC Check"
         echo ${DATE}
         echo "File Header"
         cat $gzip_file | head
         echo "Total Records"
         cat $gzip_file | wc -l
         echo "File Unique Records Size"
         cat $L0_Report_Generator | sort -u | wc -l
         rm $gzip_file 
    else [[ $gzip_file != "test_sub"*"gz" ]] #If file is anything other than .gz and csv - rort will not run
       then
         echo "incompatible file"
         fi
done
    
por B.W 25.11.2017 / 06:12

2 respostas

1

Se você quiser verificar uma extensão de nome de arquivo ".gz" usando uma expressão curinga dentro de uma instrução if, use uma expressão como a seguinte:

if [[ "${gzip_file}" = *.gz ]]; then echo true; else echo false; fi

Veja como você pode testá-lo:

if [[ "file.gz" = *.gz ]]; then echo true; else echo false; fi

e:

if [[ "file.txt" = *.gz ]]; then echo true; else echo false; fi

O primeiro exemplo produz true como saída e o segundo exemplo produz false .

Agora vamos ver seu código. Sua declaração if tem a seguinte expressão condicional:

[[ $gzip_file = "test_sub"*"gz" ]]

Em particular, você inclui "test_sub" como substring em seu padrão de correspondência. Tente remover isso.

    
por 25.11.2017 / 06:27
0

Além do que @igal disse sobre a verificação da extensão do arquivo, você tem muitos erros na sintaxe e no uso da variável. Comece com a linha 3:

L0_Report_Generator=("/home/ubuntu/$gzip_file")

A variável gzip_file ainda não foi definida, portanto $gzip_file será substituído por nada quando o shell a expandir. Além disso, os parênteses em var=(something) atribuem uma matriz em vez de uma variável simples e, nesse caso, isso não faz sentido.

A quarta linha, echo -n "Enter File Directory:"$gzip_file , tem o mesmo problema com a variável gzip_file . Ele também tem o problema de que echo -n é imprevisível e fará coisas diferentes sob diferentes versões do comando echo . Para imprimir uma string sem um avanço de linha, é muito melhor usar printf "%s" "string to print" , mas, nesse caso, há uma opção melhor que conseguirei em um minuto.

A quinta linha, read $gzip_file , parece ter a intenção de ler a entrada do usuário na variável gzip_file , mas não é isso que ela faz. No shell, quando você coloca $ na frente de um nome de variável, esse obtém o valor atual da variável. Aqui, você quer definir , então você deve deixar o $ off: read gzip_file . Mas não é isso que eu faria. Eu incluiria o prompt (que você echo na linha 4) como parte do comando read :

read -p "Enter File Directory:" gzip_file

Ok, agora para a linha 6:

for gzip_file in {$L0_Report_Generator}; do

Isso parece estar definindo gzip_file novamente (substituindo o valor que apenas read nele). Você está realmente tentando definir gzip_file aqui, e as referências de variáveis anteriores deveriam ter sido uma variável diferente (talvez gzip_dir )?

Além disso, a parte in não faz sentido. Acho que você está tentando usar a variável L0_Report_Generator , mas, nesse caso, a chave aberta deve ser após o símbolo do dólar. Mas isso também não faz sentido, porque ${L0_Report_Generator} (se eu entendi o que isso deveria fazer) é apenas o caminho para um diretório. for ... in não itera sobre o conteúdo dos diretórios, itera sobre uma lista de palavras , como for var in word1 word2 "word 3 which has several spaces in it" word4; do . Se você deseja obter uma lista de arquivos em um diretório, é necessário usar um curinga, como for var in dir/*; do - o shell expandirá o padrão de arquivo contendo curingas para uma lista de arquivos correspondentes, cada um tratado como uma palavra e iterar sobre eles. Você também tem a opção de limitar correspondências a arquivos com uma extensão específica, incluindo isso no padrão, como dir/*.gz .

Três outras notas: Recomendo que não use nomes de variáveis em maiúsculas como DATE , para evitar conflitos com as várias variáveis de ambiente em maiúsculas que têm um significado especial para o shell ou alguns utilitários. Além disso, sempre cite duas vezes suas referências de variáveis (por exemplo, use "$var" em vez de apenas $var ) para evitar esquisitices de análise inesperadas. E a cláusula else não tem um teste, portanto, usar else [[ some test ]] não faz sentido (e ter then após else é um erro de sintaxe).

Então, se eu entendi o que o script deveria fazer, recomendo substituir o início do script por:

#!/bin/bash
date=$(date +%Y-%m-%d)    # Note lowercase variable
read -p "Enter File Directory:" gzip_dir
L0_Report_Generator="/home/ubuntu/$gzip_dir"

for gzip_file in "${L0_Report_Generator}"/*.gz; do

... E então (se o padrão .gz acima é o que você quer), você não precisa do if para verificar se $gzip_file tem uma extensão .gz, porque o padrão curinga será listado apenas. arquivos gz.

Mais uma observação: o shellcheck.net é muito útil para apontar erros básicos em scripts de shell. Falta muito do que eu indiquei, mas peguei o perdedor then (que eu inicialmente senti falta).

    
por 25.11.2017 / 10:45