Curinga não sendo interpretado na instrução if

Curinga não sendo interpretado na instrução if

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

O problema que estou enfrentando está on-line 7. Não importa a extensão do arquivo, estou recebendo um arquivo incompatível como saída 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

Responder1

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

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

Aqui está 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 truecomo saída e o segundo exemplo produz false.

Agora vamos dar uma olhada no seu código. Sua instrução if tem a seguinte expressão condicional:

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

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

Responder2

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

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

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

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

A quinta linha, read $gzip_file, parece ter como objetivo 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 do nome de uma variável, issorecebeo valor atual da variável. Aqui você querdefinirisso, então você deve deixar desligado $: read gzip_file. Mas não é isso que eu faria. Eu incluiria o prompt (que você está echona linha 4) como parte do readcomando:

read -p "Enter File Directory:" gzip_file

Ok, agora para a linha 6:

for gzip_file in {$L0_Report_Generator}; do

Isso parece estar configurandogzip_file de novo(substituindo o valor que acabamos readde inserir). Você está realmente tentando definir gzip_fileaqui, e as referências de variáveis ​​anteriores realmente deveriam ter sido uma variável diferente (talvez gzip_direm vez disso)?

Além disso, a inparte não faz sentido. Acho que você está tentando usar a variável L0_Report_Generator, mas nesse caso a chave aberta deve irdepoiso cifrão. Mas isso também não faz sentido, porque ${L0_Report_Generator}(se eu entender o que isso deve fazer) será apenas o caminho para um diretório. for ... innão itera sobre o conteúdo dos diretórios, ele itera sobre uma lista depalavras, 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, você precisa usar um curinga, como for var in dir/*; do- o shell irá expandir o padrão de arquivo contendo curinga em uma lista de arquivos correspondentes, cada um tratado como uma palavra, e iterar sobre eles . Você também tem a opção de limitar as correspondências a arquivos com uma extensão específica, incluindo-a no padrão, como dir/*.gz.

Três outras notas: eu recomendo não usar nomes de variáveis ​​em letras maiúsculas como DATE, para evitar conflitos com as diversas variáveis ​​de ambiente em letras maiúsculas que têm um significado especial para o shell ou alguns utilitários. Além disso, sempre coloque aspas duplas nas referências de variáveis ​​(ou seja, use "$var"em vez de apenas $var) para evitar estranhezas inesperadas na análise. E a elsecláusula não tem teste, então usar else [[ some test ]]não faz sentido (e ter thendepois 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 for o que você deseja), você não precisa ifverificar se $gzip_filepossui uma extensão .gz, porque o padrão curinga listará apenas arquivos .gz.

Mais uma observação:shellcheck.neté muito útil para apontar erros básicos em scripts de shell. Perde muito do que apontei, mas pegou o extraviado then(que inicialmente perdi).

informação relacionada