2013-06-03 14 views
8

Czy ktoś wie jak wymienić konkretnych słów między (). Tak więc, na przykład, zastąpić słowo and z or w obu zestawów parentheseis:Zastąpić określone słowo między znakami za pomocą sed?

(stopień = 'C' i stopień = 'd' i stopień = 'E') i (int_rate> = 10 int_rate < = 20) i pub_rec> = 0 i term =”36 miesiące

byłoby to:

(stopień = 'C' lub stopień = 'D' lub klasa = 'e') i (int_rate> 10 lub int_rate < = 20) i pub_rec> = 0 i

+0

Czy można to zrobić za pomocą pojedynczego wyrażenia regularnego? –

Odpowiedz

1

naprawdę dorky podejście term =”36 miesięcy

$ 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

myślałem o nim nieco więcej i wymyślił tego rozwiązania:

$ 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' 

Zasadniczo zerwała treści w wielu liniach z separatorem jako nawias, sed użytku na wszystkich liniach z nawiasami, aby przekonwertować wszystkie i na ors, a następnie przywrócić wszystkie do pojedynczej linii.

+0

Rzuca mi następujący błąd: 'bash:! // g": nie znaleziono zdarzenia. "Myślę, że'! 'Jest zastrzeżonym słowem, a' bash' spróbuje wstawić je wewnątrz podwójnego cudzysłowu. 'polecenie z pojedynczymi cudzysłowami, a następnie jest interpretowane poprawnie. – Birei

1

To może pracować dla Ciebie (GNU sed):

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

Pracuj wstecz throught pliku zmieniającym and 's wewnątrz (...) do or wieku.

0

Jedno rozwiązanie używając

zawartości 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 

uruchomić go lubię:

vim -S script.vim infile 

która aktualizuje plik w miejscu z następujących rezultatów.

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

tworzy również plik kopii zapasowej dołączenie ~ przyrostek do oryginalnej nazwy pliku.

1

Z 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

nie wiem Sed, ale tutaj jest wyrażeniem regularnym dopasowującym tylko and jeśli następuje ):

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

Wystarczy wymienić mecze przez or tak this demo.


uwaga Side: to nie będzie sprawdzać składnię wejścia, czyli liczbę nawiasów itd Jeśli masz zamiar to zrobić, być może niektóre z istniejących parser mogłyby własnych potrzeb.