substituir palavras dependem da segunda linha [fechada]

1

Eu tenho um arquivo netlist. Eu divido linhas. O sinal de divisão é '+' no início de uma linha.

MP1 Y A VDD VDD pch_25 W=1u L=550n M=1  
MP0 Y B  
+VDD VDD pch_25 W=1u L=550n M=1  
MN1 v0 A VSS VSS nch_25_dnw W=500.0n L=550n M=1  
MN0 Y B v0 VSS nch_25_dnw W=500.0n L=550n M=1  

Gostaria de substituir o início M de cada linha por X, se essa linha contiver pch_25. Eu tenho o seguinte comando:

sed -e :a -e '$!N;s/\n+/\/;ta' -e 'P;D' file | sed '/pch_25/s/^M/X/' | sed -e 's/\/\n+/g'  

Como substituir este comando por um único sed sem pipeline?

    
por spectre 05.01.2018 / 15:32

1 resposta

0

Obviamente, o formato permite várias quebras de linha, portanto o padrão N;P;D não se encaixa muito bem: se você colecionar mais linhas, precisará imprimir e remover todas menos uma, mas P;D não faz isso é por isso que você faz o material de substituição.

Aqui está a primeira maneira que posso pensar:

sed -e :a -e '$be' -e 'N;/\n[^+]/!ba' -e :e -e 'h;s/\n[^+].*//;/pch_25/s/^M/X/;p;g;/\n[^+]/!d;s/.*\n//;ba' file

Fazemos um loop para coletar linhas até atingirmos a última linha ou uma linha que não começa com + . Em seguida, salve o padrão no espaço de espera e remova a última linha do espaço, se não estiver iniciando com + . Agora todas as linhas que formam um registro estão juntas no espaço padrão; podemos fazer a substituição desejada e imprimi-lo.

Agora, o g recupera o padrão antes de remover o início do próximo registro. Se ele não contiver uma nova linha seguida por um não- + , ele será o último registro e poderemos d excluí-lo e sair. Caso contrário, remova tudo menos a última linha e volte para marcar :a .

(Observe que você não pode simplesmente usar s/.*\n\([^+]\)//;ta , porque o t pode ser acionado por uma substituição anterior de s .)

Atualização: truque alternativo e sujo para usar N;P;D de qualquer forma:

sed -e '/^end$/d;/^+/{P;D;};:a' -e '${x;s/.*/end/;H;x;};$!N;/\n[^+]/!ba' -e '/pch_25.*\n/s/^M/X/;P;D' file
    
por 05.01.2018 / 16:04

Tags