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 true
como 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_file
ainda não foi definida, portanto $gzip_file
nã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_file
tem o mesmo problema com a variável gzip_file
. Ele também tem o problema de echo -n
ser imprevisível e fará coisas diferentes em diferentes versões do echo
comando. 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á echo
na linha 4) como parte do read
comando:
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 read
de inserir). Você está realmente tentando definir gzip_file
aqui, e as referências de variáveis anteriores realmente deveriam ter sido uma variável diferente (talvez gzip_dir
em vez disso)?
Além disso, a in
parte 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 ... in
nã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 else
cláusula não tem teste, então usar else [[ some test ]]
não faz sentido (e ter then
depois 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 if
verificar se $gzip_file
possui 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).