Excluir linhas entre 2 strings no Solaris

2

Eu quero excluir toda a linha entre dois padrões usando o awk básico ou sed.

foo.txt :

----------------------------------------------------------------------  Cap in MB
line 2
line 3
line 4
line 5
---------------------------------------------------  Cap in MB
----------------------------------------------------------------------  Cap in MB
line 2
line 3
line 4
line 5
---------------------------------------------------  Cap in MB
----------------------------------------------------------------------  Cap in MB
line 2
line 3
line 4
line 5
---------------------------------------------------  Cap in MB
----------------------------------------------------------------------  Cap in MB
line 2
line 3
line 4
line 5
----------------------------------------------------------------------  Cap in MB
line 2
line 3
line 4
line 5

output.txt :

----------------------------------------------------------------------  Cap in MB
Deleted up to this point
----------------------------------------------------------------------  Cap in MB
Deleted up to this point
----------------------------------------------------------------------  Cap in MB
Deleted up to this point
----------------------------------------------------------------------  Cap in MB
line 2
line 3
line 4
line 5
----------------------------------------------------------------------  Cap in MB
line 2
line 3
line 4
line 5

Estou usando o Solaris 5.10, o awk básico e o sed. O número de linhas entre dois padrões pode variar. Observe que a segunda string deve ser substituída, mas não a primeira string. Observe que a diferença entre dois padrões é o número de traços. O que você vê em foo.txt é exatamente o que eu tenho no meu arquivo real.

    
por ayrton_senna 03.06.2015 / 23:55

3 respostas

1
 $ awk '!f{print} /----------------------/{f=!f;if (!f)print "Deleted up to this point"}' foo.txt
----------------------------------------------------------------------  Cap in MB
Deleted up to this point
----------------------------------------------------------------------  Cap in MB
Deleted up to this point
----------------------------------------------------------------------  Cap in MB
Deleted up to this point

Como funciona

Este script tem uma variável f . Quando f é verdadeiro (1), estamos em um intervalo de linhas a serem excluídas. Quando é falso (0), estamos em um intervalo que deve ser impresso.

Por padrão, f é falso quando o programa é iniciado.

  • !f{print}

    Imprima qualquer linha quando f for falso.

  • /----------------------/{f=!f;if (!f)print "Deleted up to this point"}

    Se atingirmos a linha divisória, marcada por traços, inverta o valor de f . Se f for falso agora, imprima a mensagem "apagada".

Atualizar

O awk padrão no Solaris parece ter problemas. Experimente:

nawk '!f{print} /----------------------/{f=!f;if (!f)print "Deleted up to this point"}' foo.txt

Ou

/usr/xpg4/bin/awk '!f{print} /----------------------/{f=!f;if (!f)print "Deleted up to this point"}' foo.txt

Ou

/usr/xpg6/bin/awk '!f{print} /----------------------/{f=!f;if (!f)print "Deleted up to this point"}' foo.txt

Resposta para a pergunta revisada

$ awk ' /^---------------------------------------------------  Cap in MB/{print "Deleted up to this point"; f=0; z=""; next;} /^----------------------------------------------------------------------  Cap in MB/{f=1; if(z)print substr(z,2); z=""; print;next;}  f{z=z"\n"$0;next;} END{print substr(z,2);}' foo.txt
----------------------------------------------------------------------  Cap in MB
Deleted up to this point
----------------------------------------------------------------------  Cap in MB
Deleted up to this point
----------------------------------------------------------------------  Cap in MB
Deleted up to this point
----------------------------------------------------------------------  Cap in MB
line 2
line 3
line 4
line 5
----------------------------------------------------------------------  Cap in MB
line 2
line 3
line 4
line 5
    
por 04.06.2015 / 00:07
1

Aqui está uma solução simples com o awk: desative a impressão após a linha tracejada longa, ative a impressão após a linha tracejada a granel.

awk '
    !do_not_print {print}
    $0 == "----------------------------------------------------------------------  Cap in MB" {do_not_print = 1}
    $0 == "---------------------------------------------------  Cap in MB" {do_not_print = 0}
' <foo.txt >output.txt
    
por 04.06.2015 / 00:08
0

Minha opinião. Semelhante ao John1024, mas como o seu está em uma linha, é ilegível.
Testado em uma caixa do Solaris 8.

/usr/xpg4/bin/awk \
    -v section_start='^----------------------------------------------------------------------  Cap in MB' \
    -v delete_marker='^---------------------------------------------------  Cap in MB' \
'
    $0 ~ section_start {
        for (i=1; i<=n; i++) 
            print line[i]
        n=0
        delete line
        print
        next    
    }
    {line[++n] = $0}
    $0 ~ delete_marker {
        n=1
        delete line
        line[1] = "Deleted up to this point"
    }
    END {for (i=1; i<=n; i++) print line[i]}
' foo.txt
    
por 04.06.2015 / 17:32