2013-06-03 4 views
8

Qualcuno sa come sostituire parole specifiche tra (). Così, per esempio, sostituire la parola and con or tra le due serie di parentheseis:Sostituisci una parola specifica tra i caratteri usando sed?

(grado = 'C' e grado = 'D' e grado = 'E') e (int_rate> = 10 e int_rate < = 20) e pub_rec> = 0 e termine =' 36 mesi

Questo sarebbe:

(grado = 'C' o grade = 'D' o grade = 'E') e (int_rate> = 10 o int_rate < = 20) e pub_rec> = 0 e = termine' 36 mesi

+0

Questo può essere fatto anche con una singola espressione regolare? –

risposta

1

approccio davvero dorky:

$ sed 's/and/or/g' INPUT | sed 's/) or (/) and (/' | sed 's/\(.*\)or/\1and/' 
(grade='C' or grade='D' or grade='E') and (int_rate>=10 or int_rate<=20) and pub_rec>=0 
and term=' 36 months' 
0

Ci ho pensato un po 'di più e si avvicinò con questa soluzione:

$ sed "s/(/\n(/g" | sed "s/)/)\n/g" | sed "/(/s/and/or/g" | tr '\n' '!' | sed "s/!//g" 
(grade='C' or grade='D' or grade='E') and (int_rate>=10 or int_rate<=20) and pub_rec>=0 and term=' 36 months' 

in sostanza, si sciolse il contenuto su più righe con con separatore come parentesi, l'uso sed su tutte le linee con le parentesi per convertire tutti e gli ors in ors, quindi riportare tutto in una sola riga.

+0

Mi restituisce l'errore seguente: 'bash:! // g": evento non trovato'. Penso che '!' Sia una parola riservata e 'bash' proverà a interpolarla tra virgolette doppie. 'comando con virgolette singole e quindi viene interpretato correttamente. – Birei

1

Questo potrebbe funzionare per voi (GNU SED):

sed -r ':a;s/\band\b([^()]*\))/or\1/;ta' file 

lavorare a ritroso throught il file cambiando and 's entro (...) a or' s.

0

Una soluzione utilizzando

Contenuto script.vim

set backup 
while search(')', 'W') > 0 
    execute "normal vi)\<ESC>" 
    '<,'>s/\v%V<and>/or/ge 
    call cursor(line('.'), col('.') + 2) 
endwhile 
normal ZZ 

gestire l'IT come:

vim -S script.vim infile 

che aggiorna il file sul posto con seguente risultato.

(grade='C' or grade='D' or grade='E') and (int_rate>=10 or int_rate<=20) and pub_rec>=0 and term=' 36 months' 

crea anche un file di backup aggiungendo il ~ suffisso al nome del file originale.

1

Con perl

#!/usr/bin/perl 

$_ ="(grade='C' and grade='D' and grade='E') and (int_rate>=10 and int_rate<=20) and pub_rec>=0 and term=' 36 months'"; 
print "Before: $_\n"; 

while (/(\([^\)]+?)and(.+?\))/) { 
    s/(\([^\)]+?)and(.+?\))/$1or$2/g; 
} 
print "After: $_\n"; 
0

Non so Sed, ma qui è un'espressione regolare che corrisponde solo and se seguito da un ):

\band\b(?=[^(]*\)) 

Basta sostituire le partite da or altrettanto this demo.


Nota a margine: questo non controllerà la sintassi dell'ingresso, vale a dire il numero di parentesi, ecc Se avete intenzione di farlo, forse alcuni parser esistenti potrebbero soddisfare le vostre esigenze.