Edita iterativamente um único arquivo

2

Eu tenho um único arquivo com uma declaração parecida com esta:

myName_tx_1 VARCHAR(255)
myName_in_1 VARCHAR(255)
myName_tx_2 VARCHAR(255)
myName_in_2 VARCHAR(255)
myName_tx_3 VARCHAR(255)
myName_in_3 VARCHAR(255)
myAddress_tx_1 VARCHAR(255)
myAddress_in_2 VARCHAR(255)
etc

Eu gostaria de mudar isso para:

myName_tx_1 VARCHAR(255)
myName_in_1 VARCHAR(1)
myName_tx_2 VARCHAR(255)
myName_in_2 VARCHAR(1)
myName_tx_3 VARCHAR(255)
myName_in_3 VARCHAR(1)
myAddress_tx_1 VARCHAR(255)
myAddress_in_2 VARCHAR(1)
etc

De qualquer forma, a qualificação adicional para o problema é que eu só quero alterar as entradas onde o nome do atributo termina em 'in $' onde $ é um número (como myName_in_3 VARCHAR (255), como um exemplo).

Por acaso, os '_in' (atributos dos indicadores) vêm em pares, então fazer o n ~ 2 (ou FNR% 2 == 0) é bastante inteligente, mas eu me pergunto se é melhor identificar o '_in' $ VARCHAR (255) 'como o padrão para mudança.

Como eu faria isso usando código facilmente compreensível? O arquivo não é grande, então o desempenho não é o principal problema ... apenas tentando evitar um monte de edição manual do vi.

    
por Cloughie 21.08.2014 / 18:28

4 respostas

6

Com o GNU sed, você pode especificar os endereços de linha no formato first~step , para modificar todas as outras linhas, começando com o segundo em que você pode usar o endereço 2~2 , por exemplo,

$ sed '2~2 s/(255)/(1)/' file
myName_tx_1 VARCHAR(255)
myName_in_1 VARCHAR(1)
myName_tx_2 VARCHAR(255)
myName_in_2 VARCHAR(1)
myName_tx_3 VARCHAR(255)
myName_in_3 VARCHAR(1)
myAddress_tx_1 VARCHAR(255)
myAddress_in_2 VARCHAR(1)
    
por 21.08.2014 / 18:35
6

com awk :

$ awk 'FNR%2==0{sub(255,1)}1' file
myName_tx_1 VARCHAR(255)
myName_in_1 VARCHAR(1)
myName_tx_2 VARCHAR(255)
myName_in_2 VARCHAR(1)
myName_tx_3 VARCHAR(255)
myName_in_3 VARCHAR(1)
myAddress_tx_1 VARCHAR(255)
myAddress_in_2 VARCHAR(1)

Explicação

  • FNR%2==0 corresponde apenas a linhas pares.
  • Se a linha for par, substituímos 255 por 1 , sub(255,1) .
  • 1 é uma condição verdadeira, faça awk print $0 .

A mesma lógica pode ser usada com outras ferramentas, como perl :

perl -pe 's/255/1/ unless $. % 2' file

Com sed , você pode fazer:

sed -e 'n;s/255/1/' file

Atualizar

Com seu requisito de atualização, podemos alterar um pouco a solução.

com awk :

awk '/_in_[0-9]/{sub(255,1)}1' file

com sed :

sed -e '/_in_[0-9]/{s/255/1/}' file

com perl :

perl -pe 's/255/1/ if /_in_[0-9]/' file
    
por 21.08.2014 / 18:31
3

Existe

sed '/_in_/ s/255/1/'

que significa: para linhas que correspondem a /_in_/ , procure por 255 e substitua por 1 .

    
por 22.08.2014 / 12:46
-1
cat oldfile.txt |awk '/_in_[0-9]/{sub(255,1)}1' > newfile.txt
    
por 21.08.2014 / 19:20