Erro de sintaxe próximo do token inesperado 'else'

2

Estou tentando criar um script que removerá certas partes de um arquivo txt cheio de informações de status e outros textos diversos. Não consigo terminar a declaração principal if. Também estou tentando obtê-lo para excluir as informações de status mais antigas, colocando o comando date no script que gera o output.txt. Existe uma maneira de eliminar as informações mais antigas? Eu estou tentando principalmente fazer com que a declaração if termine. Obrigado. (Além disso, originalmente eu tinha o else como elif, mas obtive os mesmos resultados.)

./ count.sh: linha 30: erro de sintaxe próximo do token inesperado else' ./count.sh: line 30: else '

WCOUNT=$(wc -l output.txt $1 | awk '{print $1}')

if [[ $WCOUNT -gt 50 ]]; then 

    if [[ "grep CLIENTSTART output.txt" != null ]]; then
        echo $WCOUNT
        sed -i '/\*\*\*CLIENTSTART/,/CLIENTEND\*\*\*/ d' output.txt
        echo $WCOUNT

    else if [[ -n "grep DHCPSTART output.txt" ]]; then          

        echo $WCOUNT
        sed -i '/\*\*\*DHCPSTART/,/DHCPEND\*\*\*/ d' output.txt     
        echo $WCOUNT

    else if [[ -n "grep DNSSTART output.txt" ]]; then
        echo $WCOUNT
        sed -i '/\*\*\*DNSSTART/,/DNSEND\*\*\*/ d' output.txt
        echo $WCOUNT

    else if [[ -n "grep WEBSTART output.txt" ]]; then
        echo $WCOUNT
        sed -i '/\*\*\*WEBSTART/,/WEBEND\*\*\*/ d' output.txt
        echo $WCOUNT

    else
        echo "Cannot help you"
    fi

else
    echo "You're good, homie.  It's under 500"

fi
    
por Desert 16.02.2018 / 01:00

2 respostas

7

O problema aqui é que usando else if em vez de elif , você está adicionando aninhamento ao seu programa e precisará adicionar mais fi instruções para encerrar as instruções condicionais adicionais.

Aqui está uma versão editada do seu programa com um recuo ligeiramente diferente para demonstrar o que quero dizer

WCOUNT=$(wc -l output.txt $1 | awk '{print $1}')

if [[ $WCOUNT -gt 50 ]]; then 
    if [[ "grep CLIENTSTART output.txt" != null ]]; then
        echo $WCOUNT
        sed -i '/\*\*\*CLIENTSTART/,/CLIENTEND\*\*\*/ d' output.txt
        echo $WCOUNT
    else 
        if [[ -n "grep DHCPSTART output.txt" ]]; then          
            echo $WCOUNT
            sed -i '/\*\*\*DHCPSTART/,/DHCPEND\*\*\*/ d' output.txt     
            echo $WCOUNT
        else 
            if [[ -n "grep DNSSTART output.txt" ]]; then
                echo $WCOUNT
                sed -i '/\*\*\*DNSSTART/,/DNSEND\*\*\*/ d' output.txt
                echo $WCOUNT
            else 
                if [[ -n "grep WEBSTART output.txt" ]]; then
                    echo $WCOUNT
                    sed -i '/\*\*\*WEBSTART/,/WEBEND\*\*\*/ d' output.txt
                    echo $WCOUNT
                else
                    echo "Cannot help you"
                fi
            fi
        fi
    fi
else
    echo "You're good, homie.  It's under 500"

fi

Como alternativa, você pode usar apenas elif

WCOUNT=$(wc -l output.txt $1 | awk '{print $1}')

if [[ $WCOUNT -gt 50 ]]; then 

    if [[ "grep CLIENTSTART output.txt" != null ]]; then
        echo $WCOUNT
        sed -i '/\*\*\*CLIENTSTART/,/CLIENTEND\*\*\*/ d' output.txt
        echo $WCOUNT

    elif [[ -n "grep DHCPSTART output.txt" ]]; then          

        echo $WCOUNT
        sed -i '/\*\*\*DHCPSTART/,/DHCPEND\*\*\*/ d' output.txt     
        echo $WCOUNT

    elif [[ -n "grep DNSSTART output.txt" ]]; then
        echo $WCOUNT
        sed -i '/\*\*\*DNSSTART/,/DNSEND\*\*\*/ d' output.txt
        echo $WCOUNT

    elif [[ -n "grep WEBSTART output.txt" ]]; then
        echo $WCOUNT
        sed -i '/\*\*\*WEBSTART/,/WEBEND\*\*\*/ d' output.txt
        echo $WCOUNT

    else
        echo "Cannot help you"
    fi

else
    echo "You're good, homie.  It's under 500"

fi

(Além disso, o pequeno nitpick, você está verificando se há mais de 50 linhas, mas sua mensagem de saída indica que você está verificando 500. Embora tecnicamente, há menos de 500 linhas, é um pouco enganador: p)

EDIT: Como outros apontaram, isso corrigirá seu erro de sintaxe, mas ainda há outros problemas com o script. Eu recomendaria ler seus comentários / respostas também.

    
por 16.02.2018 / 01:25
1

O motivo pelo qual você está recebendo um erro de sintaxe é que suas instruções else if devem ser elif .

Se você der wc -l dois arquivos, ele produzirá três linhas de saída:

$ wc -l .profile .profile
      30 .profile
      30 .profile
      60 total

Isso afeta o primeiro if test, em que $WCOUNT não é marcado e sua expansão apresenta outro erro de sintaxe.

Você provavelmente quer

WCOUNT=$( wc -l <output.txt )

Além disso, você tem vários testes em strings como "grep DHCPSTART output.txt" . Esses testes sempre serão verdadeiros.

Para testar se uma string está presente em um arquivo, use

if grep -Fq 'fixed string' filename; then

por exemplo,

if grep -Fq 'CLIENTSTART' output.txt; then
   # do something
elif grep -Fq 'DHCPSTART' output.txt; then
   # do something
else
   # do something
fi

O -q impede que grep produza qualquer saída real. Seu status de saída informará se a string foi encontrada ou não e é isso que faz com que a instrução if funcione (o sinalizador também faz com que grep pare de ler o arquivo na primeira correspondência). O -F flag faz com que grep trate o padrão fornecido como uma string fixa em vez de uma expressão regular.

Sugestão para os aspectos internos do seu script:

tmpfile=$(mktemp)

for string in CLIENT DHCP DNS WEB; do
    if grep -Fq "${string}START" output.txt; then
        sed "/\*\*\*${string}START/,/${string}END\*\*\*/d" \
            output.txt >"$tmpfile"
        break
    fi
done

if [ -s "$tmpfile" ]; then
    mv "$tmpfile" output.txt
else
    echo 'Can not help you'
    rm -f "$tmpfile"
fi

O teste [ -s "$tmpfile" ] será bem-sucedido se o arquivo $tmpfile tiver tamanho maior que zero (o que ocorrerá se sed tiver sido invocado).

O loop for com o break imita sua lógica if ... then ... elif , mas de uma maneira mais compacta.

    
por 16.02.2018 / 09:55