Substituindo expressões por 'sed'

1

Eu tenho um arquivo SQL que contém muitas instruções INSERT , mas elas são todas combinadas em uma linha. Eu estava tentando usar sed para separá-los em linhas diferentes, mas não consegui fazê-lo funcionar. Aqui está o comando que estou usando:

sed 's/);INSERT/);\nINSERT/' myfile.sql

Mas este comando não está funcionando. O que há de errado com isso? Como posso consertar isso?

    
por Hosam Aly 03.08.2009 / 10:53

3 respostas

10

Adicione um "g" ao final do regex para dizer a ele para funcionar em todas as correspondências, em vez de apenas no primeiro encontrado.

sed 's/);INSERT/);\nINSERT/g' myfile.sql
    
por 03.08.2009 / 10:59
2

de onde veio o arquivo?

se for de um Mac, provavelmente haverá um retorno de carro ("\ r" ou ASCII 0x13) após o ponto e vírgula. Os Macs usam o CR como um separador de linha, enquanto o * nix usa caracteres de alimentação de linha, também conhecidos como "newline" ("\ n" ou ASCII 0x0a).

MS-Dos / Windows usa a sequência de dois caracteres CR / LF ("\ r \ n") para separar as linhas.

também, se a entrada for toda uma linha, o s / search / replace / substituirá apenas a correspondência first na linha. você precisa do modificador g para torná-lo uma pesquisa e substituição "global".

meu palpite é que o arquivo é de um Mac porque você diz que é tudo apenas uma linha ... um arquivo do Windows ainda seria tratado como várias linhas (porque existe um \ n para ver unix).

tente algo como:

sed 's/);[\n\r]*INSERT/);\nINSERT/g' myfile.sql

que corresponderá à sua string com zero ou mais de \ n e / ou caracteres imediatamente após o ponto e vírgula. observe também o modificador / g.

se isso falhar, eu estaria inclinado a tentar perl ao invés de sed (mas eu prefiro perl REs de qualquer maneira). você pode fazer o slurp de todo o arquivo em uma string escalar e usar os modificadores / s e / g para ignorar praticamente os fins de linha. você também pode usar a classe de caractere \ R que corresponde a qualquer terminação de linha conhecida - de acordo com a página man perlre, ela corresponde:

(? > \ x0D \ x0A? | [\ x0A- \ x0C \ x85 \ x {2028} \ x {2029}])

    
por 03.08.2009 / 11:19
1
  • Em vez de \ n, insira um caractere de controle-M. Você pode fazer isso na maioria dos shells modernos digitando control-V control-M.
  • Além disso, não esqueça / g para tornar a mudança global para tudo na linha.

.

 sed 's/);INSERT/);^MINSERT/g' myfile.sql
                   |
                  control-V control-M
    
por 03.08.2009 / 11:50