Como alterar um caractere em uma determinada linha sem delimitadores com awk

0

Eu tenho um arquivo e gostaria de alterar um único caractere nas linhas 400 a 600. O caractere é o 22º caractere em cada linha. É também a quinta coluna, então eu tentei o seguinte:

awk '{if (NR>=400 && NR <=600) $5="B"; print}' file.txt

O problema é que, entre cada coluna, há um número preciso de espaços que são substituídos por um único espaço quando eu faço isso. Como posso alterar um único caractere sem tocar em nenhum outro caractere, incluindo delimitadores, dentro de um intervalo de linha?

    
por sodiumnitrate 31.05.2016 / 21:05

2 respostas

1

A maneira elegante é tratar cada personagem de um campo. Se você definir FS para a string vazia, o awk irá dividi-los dessa maneira. Então você pode definir o 22º campo para o que você deseja que seja. Apenas lembre-se de configurar o OFS para a string vazia, de modo que não haja espaços (padrão OFS) entre todos os caracteres na saída.

awk -vFS="" -vOFS="" 'NR==400,NR==600 {$22="B"}; {print}'

Obviamente, este fará divisões desnecessárias em linhas fora do intervalo. Poderíamos definir os separadores de campo pouco antes da 400ª linha e depois do 600º. Mas por que dividir tudo aqui quando temos substr ()? Vamos apenas criar uma string com os primeiros 21 caracteres + "B" + o resto da linha original para as linhas importantes.

awk  '{s=$0}; NR==400,NR==600 { s=substr($0,1,21) "B" substr($0,23)}; {print s}'

(É possível fazer isso sem s, apenas atribuindo $ 0 a seu novo valor, mas quando atribuímos $ 0, ele é re-dividido de acordo com as regras, e não há razão para sacrificar a velocidade para essa etapa agora.)

    
por 31.05.2016 / 22:14
0

Você também pode usar sed :

sed -r '400,600s/(.{21}).(.*)/B/' file.txt
    
por 07.06.2016 / 16:11

Tags