2012-04-25 17 views
21

Mam problem z ustaleniem, jak używać sed do wyszukiwania i zamiany ciągów zawierających znak / w pliku tekstowym /etc/myconfig.sed wyszukaj i zamień ciągi zawierające/

Na przykład w moim istniejącego pliku tekstowego, mam:

myparam /path/to/a argB=/path/to/B xo 

i chcę ten otrzymuje brzmienie:

myparam /path/to/c argB=/path/to/D xo 

próbowałem robić to w bash:

line='myparam /path/to/a argB=/path/to/B xo' 
line_new='myparam /path/to/c argB=/path/to/D xo' 
sed -i 's/$line/$line_new/g' /etc/myconfig 

Ale nic się nie dzieje.

Próba

grep -rn "$line" /etc/myconfig 

ma powrócić mnie 'myparam /path/to/a argB=/path/to/B xo' chociaż.

Jaki jest prawidłowy sposób wyrażenia mojej komendy sed w celu wykonania tego wyszukiwania i zastąpienia i poprawnego działania z poleceniem /? (Sądzę, że ten znak jest jednym z problemów, ponieważ użyłem podobnej komendy sed, aby wyszukać i zastąpić inną linię w pliku tekstowym bez żadnych problemów, a ta linia nie ma postaci /.

+1

Zasady zastępowania i cytowania dotyczą raczej basha, a nie sed. Możesz dodać bash jako tag. – KarlM

+0

ok. doda 'bash' jako tag. –

Odpowiedz

32

nie uciec backslashy, będziesz się mylić Użyj innego symbolu po komendzie s że nie pojawia się w tekście (używam % w przykładzie poniżej):

line_old='myparam /path/to/a argB=/path/to/B xo' 
line_new='myparam /path/to/c argB=/path/to/D xo' 
sed -i "s%$line_old%$line_new%g" /etc/myconfig 

również. , ująć cały ciąg w podwójne cudzysłowy, używając pojedynczych cudzysłowów oznacza, że ​​sed widzi $line (w oryginale) zamiast rozwiniętej wartości. Wewnątrz pojedynczych cudzysłowów nie ma rozszerzenia i nie ma metaznaków. Jeśli Twój tekst może zawierać prawie dowolny zwykły tekst, użyj znaku kontrolnego (na przykład control-A lub control-G) jako ogranicznika.

Należy pamiętać, że użycie -i tutaj odzwierciedla to, co jest w pytaniu, ale to zakłada użycie GNU sed. BSD sed (również w systemie Mac OS X) wymaga przyrostka. Możesz użyć sed -i '' …, aby zastąpić na miejscu; to nie działa z GNU sed. Aby być przenośnym między tymi dwoma, użyj -i.bak; to będzie działać z obydwoma - ale da ci plik kopii zapasowej, który prawdopodobnie zechcesz usunąć. Inne platformy uniksowe (na przykład AIX, HP-UX, Solaris) mogą mieć warianty sed, które w ogóle nie obsługują -i. Nie jest to wymagane przez specyfikację POSIX dla sed.

+0

dzięki!Podwójny cudzysłów '' 'i'% 'zmyślił.I starałem się uniknąć znaku'/'wykonując' \/'i to nie działało w ogóle. –

+0

Pamiętaj, że jeśli musisz określić zakres linii przez regex, a regex zawiera ukośniki, możesz użyć 'sed -n '\ @ dir/file @, \ @ dir2/file2 @ p', gdzie ukośnik odwrotny przed' @ 'wskazuje, że' @ 'jest ogranicznikiem wyszukiwania dla To wyrażenie: –

+0

Zauważ, że ktoś może potrzebować 'sed -i -e' – PhysicalChemist

12

To może pracować dla Ciebie:

sed -i "s|$line|$line_new|g" /etc/myconfig 

Musisz użyć " jest tak, że $line i $new_line są interpolowane. Użyj także | lub dowolnego znaku nie znalezionego w łańcuchu dopasowania lub zastępczym jako ogranicznika.

+1

ok. Nie wiedziałem o sztuczce "|". Czyli chcesz powiedzieć, że Dowolny ogranicznik będzie działać tak długo, jak długo nie będzie to znak znaleziony w łańcuchach wyszukiwania lub zamiany? –

+0

Tak; pierwszy znak po 's' jest używany do rozdzielenia polecenia na dwie części; wzór do dopasowania i wzór zastępczy. 's/search/replace /' używa '/' trzy razy; ale 's | search | replace |' lub 's% search% replace%' również działa. Perl pozwala na dopasowanie nawiasów klamrowych ('s {search} {replace}'), ale 'sed' nie (chyba, że ​​aktywowałeś opcję wzorców Perla, jeśli masz GNU' sed'). –

+1

Tak, w granicach rozsądku. '|' jest przydatny do użycia, ponieważ nie pojawia się w pliku. Jednak jest to metaznak (używany na przemian), więc jeśli chcesz powiedzieć 's/this \ | that/these /', użyj innego separatora, takiego jak '@' lub '#' lub ',' lub '?' Lub ' % 'itd. Należy również zauważyć, że jest to dla polecenia substytucji dla polecenia wyszukiwania' /.../ 'do używania alternatywnego separatora poprzedzającego alternatywę z odwrotnym ukośnikiem np. '\ | foo |' – potong

Powiązane problemy