Mover uma linha antes da outra em um arquivo sed multi-command

2

.

Eu tenho um arquivo de texto semelhante a este:

A
B
C
D
E
F
G

e eu preciso:

  1. mova a linha E antes da linha C ;
  2. substitua a linha C por X ( X poderia ser multilinha);
  3. substitua a linha G por Y ( Y poderia ser multilinha);
  4. remova as linhas D e F .

Este é o arquivo sed que tenho agora:

/C/ c\
X
/G/ c\
Y
/D/ d
/F/ d

que faz 2, 3, 4 mas não 1. Como posso corrigir o script para mover E antes de C ?

Nota: não posso confiar em números de linhas ou contiguidade de linhas, que podem variar; Eu só posso confiar na correspondência de padrões.

    
por Giovanni Lovato 21.10.2018 / 07:20

1 resposta

5

Para o seu caso em particular, isso funcionará:

sed '
/C/,/E/ {
        s/[CD]/&/
        t s
        s/E.*/&\
X1\
X2/
        t e
        H
        :s
        d
        :e
        p
        x
        D
}
/F/d
/G/c\
Y1\
Y2
' file

Alguém mais inteligente do que eu pode ser capaz de fazer isso de uma forma mais simples - observe que isso deve lidar com o caso em que há outras linhas além de D entre C e E . Isso pressupõe, no entanto, que as linhas A , B , ... sejam classificadas, ou seja, sem G entre C e D .

Geralmente, casos como esse são feitos muito mais obviamente com ed ou ex :

$ cat <<EOT | ed -s file
/E/m/C/-1
g/D/d
g/F/d
/C/c
X1
X2
.
/G/c
Y1
Y2
.
w
EOT

$ cat file
A
B
E
X1
X2
Y1
Y2

O comando /PAT1/m/PAT2/-1 moverá a linha correspondente a PAT1 antes da linha corresponder a PAT2 .

O comando /PAT/c alterará a linha correspondente a PAT para as seguintes linhas terminadas por . .

O comando g/PAT/d irá para todas as linhas correspondentes a PAT e as excluirá.

Alterei a ordem das operações com base nas sugestões do @ don_crissti, para tornar o exemplo um pouco mais geral (manipule o caso em que as linhas X1 , Y1 inseridas podem corresponder ao /D/ ou /F/ padrões).

    
por 21.10.2018 / 09:19

Tags