za pomocą sed z ampersand (&)

19

Używam sed do znajdowania i zastępowania wzorców w plikach SAS, które mam, zamiast zmieniać je indywidualnie. Problem polega na tym, że próbuję zastąpić makrozmienne, a gdy używam ampersand, nie przetwarza to poprawnie.

Here's my code:
sed -ie 's/user=&uid./user=&sysuserid./g' *_table_*.sas

za każdym razem, gdy uruchamiam to polecenie, wydaje się, że dołącza się i wykonuje różne czynności z oryginalnym tekstem.

Pytanie: Jak zastąpić tekst zawierający znaki ampersand poleceniem sed?

lucasdavis500
źródło
6
&jest postacią specjalną, dlatego należy go uciec, gdy jest używany w RHS - w twoim przypadku musisz biec, 's/user=&uid./user=\&sysuserid./g'chociaż podejrzewam, że musisz także uciec z kropki w LHS, aby dopasować dosłowną kropkę, więc naprawdę potrzebujesz's/user=&uid\./user=\&sysuserid./g'
don_crissti
1
tak, „&” po prawej stronie oznacza w zasadzie „wszystko, co pasowało po lewej”, więc unikaj tego za pomocą „\”. Powinieneś udzielić odpowiedzi, a nie tylko komentarza.
Edward Falk,
nie
musiałem

Odpowiedzi:

25

&jest wyjątkowy w tekście zastępczym: oznacza „całą część danych wejściowych, która została dopasowana do wzorca”, więc to, co tutaj robisz, zastępuje user=&uidXsię user=user=&uidXsysuserid.. Aby wstawić rzeczywistą ampersand do tekstu zastępczego, użyj \&.

Kolejną rzeczą, która wygląda źle, jest to, że .wzorzec wyszukiwania oznacza dowolny znak (oprócz nowej linii), ale .na końcu tekstu zastępczego jest dosłowna kropka. Jeśli chcesz zastąpić tylko ciąg literalny user=&uid., chroń go .odwrotnym ukośnikiem.

sed -e 's/user=&uid\./user=\&sysuserid./g'

Jeśli chcesz zastąpić dowolny znak i zachować go w wyniku, umieść go w grupie i użyj \1w zamianie, aby odnieść się do tej grupy.

sed -e 's/user=&uid\(.\)/user=\&sysuserid\1/g'

W rzeczywistości, biorąc pod uwagę powtórzenie między oryginalnym tekstem a zamiennikiem, i tak powinieneś używać grup:

sed -e 's/\(user=&\)u\(id\.\)/\1sysuser\2/g'

tzn. „zamień una sysuserpomiędzy user=&i id.”.

Gilles „SO- przestań być zły”
źródło
czy mógłbyś wyjaśnić grupy?
lucasdavis500,
2
@ lucasdavis500 Grupa identyfikuje część wzorca. Jest ograniczony nawiasami ukośnymi. Na przykład \(user=&\)jest wzorcem, który pasuje user&i przechowuje ciąg dopasowania jako grupę (grupa numer 1, ponieważ jest to pierwsza grupa we wzorcu). Następnie w zastępstwie \1zastępuje się ciąg zapisany dla grupy numer 1.
Gilles „SO- przestań być zły”
masz na myśli (użytkownik = i) przechowuje użytkownika = i nie użytkownika i?
lucasdavis500,
@ lucasdavis500 Nie rozumiem twojego komentarza. Znak =w wyrażeniach regularnych i w tekście zastępczym oznacza sam dla siebie, więc user=&pasuje tylko user=&, a user=&w tekście zastępczym pojawia user=się część wiersza dopasowana przez wyrażenie regularne.
Gilles „SO- przestań być zły”
1
@ lucasdavis500 =Postać nie ma żadnego specjalnego znaczenia. user=&w tekście zastępczym powstaje user=następujący po nim oryginalny dopasowany tekst. user=\&w tekście zastępczym produkujeuser=&
Gilles „SO- przestań być zły”