como posso comentar / em uma seção no código-fonte com sed ou awk

1

Atualmente eu tenho arquivos, que contêm seções como esta

code statement1
code statement2
# BEGIN SOMENAME
some code
some other code
# END SOMENAME
code statement n +1
code statement n +1

O que eu quero fazer é comentar o que há entre "# BEGIN SOMENAME" e "# END", para que, no final, pareça com isso

code statement1
code statement2
# BEGIN SOMENAME
# some code
# some other code
# END SOMENAME
code statement n +1
code statement n +1

Posso conseguir isso com o awk ou sed? e posso reverter isso facilmente ?, então apenas uma operação, que "comenta de novo"?

O que eu quero evitar cometer erros, por isso, se as linhas já estão comentadas deve ser deixado sozinho. Também em "comment in", ele não deve tentar fazer algo se as linhas entre end e begin não começarem com um "#".

Tentei isso agora por várias horas, sem sucesso.

Encontrou uma possível solução:

awk '
BEGIN                      { i=0; line_with_no_comment_found=0 }
/^# END/                  { m=0;
                             if ( line_with_no_comment_found == 1 )
                               { for (var in a) print "# "a[var] }
                             else
                               { for (var in a) print a[var] }
                             delete a;
                             i=0;
                             line_with_no_comment_found=0;
                           }
/^# /                      { if (m==0) { print } else { a[i++]=$0; } }
!/^# /                     { if (m==0) { print } else { a[i++]=$0; line_with_no_comment_found=1} }
/^# BEGIN ([a-zA-Z_])([1-9][0-9]*)*/ {m=1;}
END { }
'<<EOF
    
por Mandragor 02.02.2016 / 16:19

1 resposta

0

Este script funciona para mim. Eu testei no GNU Awk 4.0.1, mas também deveria funcionar em Nawk.

awk 'BEGIN {
    # action=0: uncomment
    # action=1: comment
    action=0
    in_optional_code_block=0
}
{
    if ($0 ~ /^# BEGIN/) {
        in_optional_code_block=1
    } else if ($0 ~ /^# END/) {
        in_optional_code_block=0
    } else if (in_optional_code_block) {
        if (action) {
            if ($0 !~ /^#/) {
                $0 = "# " $0
            }
        } else {
            if ($0 ~ /^#/) {
                sub(/^# ?/, "")
            }
        }
    }
}
1'

Também escrevi um pequeno script de acompanhamento:

#!/usr/bin/env sh

syntax_error() {
    echo "Usage: 'basename \"$0\"' [comment|uncomment] file" >&2
    exit 1
}

case "$1" in
    0|uncomment) action=0; ;;
    1|comment) action=1; ;;
    *) syntax_error; ;;
esac
shift
if [ -z "$@" ]; then syntax_error; fi

awk 'BEGIN {
    action='$action'
    in_optional_code_block=0
}
{
    if ($0 ~ /^# BEGIN/) {
        in_optional_code_block=1
    } else if ($0 ~ /^# END/) {
        in_optional_code_block=0
    } else if (in_optional_code_block) {
        if (action) {
            if ($0 !~ /^#/) {
                $0 = "# " $0
            }
        } else {
            if ($0 ~ /^#/) {
                sub(/^# ?/, "")
            }
        }
    }
}
1' "$@" > "[email protected]"
if [ $? -eq 0 ]; then mv "[email protected]" "$@"; fi

(Se você tiver o GNU Awk 4.1.0 ou posterior, você pode usar o sinalizador -i em vez da construção de movimentação no final.)

    
por 05.02.2016 / 22:40

Tags