Awk: instrução if e condicional no mesmo bloco

Awk: instrução if e condicional no mesmo bloco

Aqui está o código de um script onde devo verificar se o nome do arquivo é 'pretempsc.cfg' e imprimir seu conteúdo como está. . Para qualquer outro arquivo, devo modificar apenas as linhas que começam com 'abc disable ...' para 'no abc ...'.

    #!/bin/sh
    IN_FILE=$1
    OUT_FILE=$2

    WhatFileIsIt() {
    awk -v filename=$IN_FILE '
    BEGIN {
        scnode = 0;
        if (filename == "pretempsc.cfg") {
            scnode = 1; }
    }
    {
        if (!scnode) {
            /^abc disable/ {
            print "no abc "$4"";
            next;
            }

            print;}
        }
        else {print}
    }
    '
    }

    cat $IN_FILE | WhatFileIsIt | cat > $OUT_FILE

Ao executar este script, recebo o seguinte erro:

 awk: cmd. line:9:         /^abc disable/ {
 awk: cmd. line:9:                        ^ syntax error
 awk: cmd. line:16:     else {print}
 awk: cmd. line:16:     ^ syntax error

Pelo que pude observar, suspeito que estou errado no uso de if e condição-ação dentro do bloco de ação, mas não consigo descobrir exatamente o que está errado.

Para observar: DEVO usar awk dentro do script de shell, e há muitas outras funções semelhantes a WhatFileIsIt fazendo seu próprio processamento no IN_FILE.

Responder1

Sim, você precisa alterar essa correspondência de padrão para uma ifinstrução completa:

if (/^abc disable/) {
    print "no abc "$4"";
    next;
}

( /pattern/é uma abreviação de $0 ~ /pattern/, onde $0contém toda a linha de entrada.)

Observe que printlá imprime apenas a quarta coluna da entrada depois de no abc, então abc disable foo bar doose transforma em apenas no abc bar. Não tenho certeza se era isso que você queria.


Enquanto estamos nisso, algumas outras coisas vêm à mente... Sinta-se à vontade para ignorar qualquer uma dessas coisas, se elas forem muito óbvias ou entrarem em conflito com o resto do seu roteiro. (E espero não ter cometido muitos erros.)

Acho que há uma chave extra direita no final do print, e parece que o recuo da condição mais profunda está um pouco errado, então reescreva um pouco:

{
    if (!scnode) {
        if (/^abc disable/) {
            print "no abc " $4;
            next;
        }
        print;
    } else {
        print;
    }
}

Mas a partir daqui, parece que a única vez que algo especial é feito é quando ambos !scnodesão verdadeiros e /^abc disable/correspondem; em todos os outros casos, há apenas o print. Portanto, poderíamos combinar as condições com &&(é claro que a separação entre diferentes tipos de arquivos não é mais tão clara):

{
    if (!scnode && /^abc disable/) {
        print "no abc "$4"";
        next;
    } else {
        print;
    }
}

Como existe um nextque encurta a execução, o final printpode ficar sem a elsecláusula e, de fato, como todo o bloco de código é apenas um if, poderíamos deixar a condição cair no nível principal e seguir com uma ação padrão incondicional de impressão.

!scnode && /^abc disable/ {
    print "no abc "$4"";
    next;
}
1;

(É claro que isso pode parecer um pouco condensado agora.)


Além disso, no shell script, você não precisa incomodar os gatos, é melhor deixá-los dormindo e usar apenas o shell para redirecionamento. (E cite as variáveis ​​​​do shell.)

 WhatFileIsIt < "$IN_FILE" > "$OUT_FILE"

O nome dessa função é um pouco confuso, ela realmente não responde a nenhuma pergunta "o quê", mas processa um arquivo. Talvez algo como ProcessFile?

E bem, falando em funções, essa função usa a variável IN_FILE, que não é local para ela. Pode ser confuso se houver necessidade de executar uma função para dois arquivos diferentes. Assim como o próprio script de shell, a função também pode receber parâmetros, chamar MyFunction fooe fazer $1conter foodentro da função.

Então talvez eu fizesse algo como

ProcessFile() {
awk < "$1" -v filename="$1" '
[...]

(Não importa se você coloca o redirecionamento de entrada no meio ou no final da linha de comando do awk.)

Usar com:

ProcessFile "$IN_FILE" > "$OUT_FILE"

informação relacionada