El comodín no se interpreta en la declaración if

El comodín no se interpreta en la declaración if

Actualmente estoy escribiendo el siguiente guión. El código busca en un directorio determinado un nombre de archivo ingresado por el usuario. El script primero verifica si el archivo de entrada es un gzip; de ser así, ejecuta las comprobaciones correspondientes. Si el archivo no está comprimido con gzip, responde con un texto de archivo incompatible.

El problema con el que me encuentro está en línea 7. No importa la extensión del archivo, recibo un archivo incompatible 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

Respuesta1

Si desea verificar si hay una extensión de nombre de archivo ".gz" usando una expresión comodín dentro de una declaración if, entonces usaría una expresión como la siguiente:

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

Así es como puedes probarlo:

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

y:

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

El primer ejemplo produce truecomo resultado y el segundo ejemplo produce false.

Ahora veamos su código. En su lugar, su declaración if tiene la siguiente expresión condicional:

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

En particular, estás incluyendo "test_sub" como una subcadena en tu patrón de coincidencia. Intenta eliminar eso.

Respuesta2

Además de lo que dijo @igal sobre verificar la extensión del archivo, tiene muchos errores en la sintaxis y el uso de las variables. Comience con la línea 3:

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

La variable gzip_fileaún no se ha configurado, por lo que $gzip_fileno será reemplazada por nada cuando el shell la expanda. Además, el paréntesis var=(something)asigna una matriz en lugar de una variable simple, y en este caso eso no tiene ningún sentido.

La cuarta línea, echo -n "Enter File Directory:"$gzip_filetiene el mismo problema con la variable gzip_file. También tiene el problema de que echo -nes impredecible y hará cosas diferentes bajo diferentes versiones del echocomando. Para imprimir una cadena sin salto de línea, es mucho mejor usar printf "%s" "string to print", pero en este caso hay una opción mejor a la que hablaré en un minuto.

La quinta línea read $gzip_file, parece estar destinada a leer la entrada del usuario en la variable gzip_file, pero eso no es lo que hace. En el shell, cuando pones $delante de un nombre de variable, esoobtieneel valor actual de la variable. aquí quierescolocarasí que debes dejar apagado $: read gzip_file. Pero eso no es lo que haría. Incluiría el mensaje (que está echoen la línea 4) como parte del readcomando:

read -p "Enter File Directory:" gzip_file

Bien, ahora para la línea 6:

for gzip_file in {$L0_Report_Generator}; do

Esto parece estar estableciendogzip_file de nuevo(reemplazando el valor que acabamos readde introducir). ¿Realmente estás intentando configurar gzip_fileaquí y las referencias de variables anteriores realmente deberían haber sido una variable diferente (tal vez gzip_diren su lugar)?

Además, la inparte no tiene ningún sentido. Creo que estás intentando usar la variable L0_Report_Generator, pero en ese caso la llave abierta debería irdespuésel signo del dólar. Pero eso tampoco tiene del todo sentido, porque ${L0_Report_Generator}(si entiendo lo que se supone que debe hacer) será simplemente la ruta a un directorio. for ... inno itera sobre el contenido de directorios, itera sobre una lista depalabras, como for var in word1 word2 "word 3 which has several spaces in it" word4; do. Si desea obtener una lista de archivos en un directorio, necesita usar un comodín, como for var in dir/*; do: el shell expandirá el patrón de archivo que contiene comodines en una lista de archivos coincidentes, cada uno tratado como una palabra, y los iterará sobre ellos. . También tiene la opción de limitar las coincidencias a archivos con una extensión específica incluyéndola en el patrón, como dir/*.gz.

Otras tres notas: recomiendo no usar nombres de variables en mayúsculas como DATE, para evitar conflictos con las diversas variables de entorno en mayúsculas que tienen un significado especial para el shell o algunas utilidades. Además, siempre coloque comillas dobles en las referencias de sus variables (es decir, use "$var"en lugar de just $var) para evitar rarezas inesperadas en el análisis. Y la elsecláusula no tiene prueba, por lo que usar else [[ some test ]]no tiene sentido (y tener thendespués elsees un error de sintaxis).

Entonces, si entendí lo que se supone que debe hacer el script, recomendaría reemplazar el comienzo del script con:

#!/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

...Y luego (si lo que desea es el patrón .gz anterior), no necesita ifverificar si $gzip_filetiene una extensión .gz, porque el patrón comodín solo enumerará archivos .gz.

Una nota más:shellcheck.netes muy útil para señalar errores básicos en los scripts de shell. Se pierde mucho de lo que señalé, pero captó lo extraviado then(que inicialmente me perdí).

información relacionada