Pytanie w sprawie sed – sed: Zastąp część linii

34

Jak można zastąpić część linii sedem?

Linia

DBSERVERNAME     xxx

należy zastąpić:

DBSERVERNAME     yyy

Wartość xxx może się różnić i istnieją dwie karty między nazwą_serwera_db i wartością. Ta para nazwa-wartość jest jedną z wielu z pliku konfiguracyjnego.

Próbowałem z następującą referencją wsteczną:

echo "DBSERVERNAME    xxx" | sed -rne 's/\(dbservername\)[[:blank:]]+\([[:alpha:]]+\)/\1 yyy/gip'

i to spowodowało błąd: nieprawidłowe odwołanie 1 do RHS polecenia `s '.

Co jest nie tak z tym wyrażeniem? Używanie GNU sed.

Twoja odpowiedź

7   odpowiedzi
1

Może to działać dla ciebie:

echo "DBSERVERNAME     xxx" | sed 's/\S*$/yyy/'
DBSERVERNAME     yyy
1

Nie powinieneś uciekać przed swoimi parenami. Próbować:

echo "DBSERVERNAME    xxx" | sed -rne 's/(dbservername)[[:blank:]]+([[:alpha:]]+)/\1 yyy/gip'
1

gdy używasz pojedynczych cudzysłowów. to znaczy.

echo "DBSERVERNAME    xxx" | sed -rne 's/(dbservername[[:blank:]]+)([[:alpha:]]+)/\1 yyy/gip'
0

sed -re 's/DBSERVERNAME[ \t]*([^\S]+)/\yyy/ig' temp.txt

albo to

awk '{if($1=="DBSERVERNAME") $2 ="YYY"} {print $0;}' temp.txt

42

To działa:

sed -rne 's/(dbservername)\s+\w+/\1 yyy/gip'

(Gdy używasz opcji -r, nie musisz uciekać przed parens).

Trochę wyjaśnienia:

-r to rozszerzone wyrażenia regularne - robi różnicę w sposobie zapisywania wyrażenia regularnego.-n nie drukuje, chyba że określono -sed domyślnie drukuje inaczej,-e oznacza to, co następuje, to wyrażenie. Złammy to wyrażenie:s/// jest poleceniem dla search-replace, a między pierwszą parą jest wyrażenie regularne, które ma być dopasowane, a drugą parą zamiennik,gip, który następuje po poleceniu wyszukiwania;g oznacza globalny, tj. każde dopasowanie zamiast tylko pierwszego zostanie zastąpione w linii;i jest niewrażliwość na wielkość liter;p oznacza drukowanie po zakończeniu (pamiętaj o-n flaga z wcześniejszego!),Nawiasy reprezentują część meczu, która pojawi się później. Więcdbservername to pierwsza część meczu,\s to białe znaki,+ oznacza jeden lub więcej (vs*, zero lub więcej) zdarzeń,\w to słowo, czyli dowolna litera, cyfra lub podkreślenie,\1 to specjalne wyrażenie dla GNUsed , który drukuje pierwszy mecz w nawiasie w wyszukiwaniu towarzyszącym.
Wiem, że macie dużo doświadczenia w komendach powłoki ... ale proszę dbać o aspirujące linux noobs tam, gdzie to możliwe ... wszystko w środku'' musi zostać wyjaśnione ... albo muszę przejść przez całośćdoc Mahesha999
8

ale dlaczego w ogóle potrzebujesz referencji, jeśli pierwsza część linii jest stała?

Możesz po prostu to zrobić

sed -e 's/dbservername.*$/dbservername yyy/g'
To daje mi głos, ponieważ jest to najprostsze rozwiązanie prostego problemu. Użycie wstecznej referencji uchroniłoby Cię przed błędnym wpisaniem dwóch kopiidbservername. Jest to oczywiste, ale kiedy modyfikuję postgresql.conf w sed, trudno mi na pierwszy rzut oka sprawdzić, czy wpisałemlisten_address lublisten_addresses (postgresql.conf). Oba wyglądają wiarygodnie, ale tylko jedno jest poprawne. Iain Samuel McLean Elder
Słuszna uwaga! Właśnie dowiedziałem się o używaniu regexps + sed i mind po prostu zdecydowałem się na „regexp” podczas oglądania tego konkretnego zadania, a następnie jako „jwz” powiedziałem „miałem dwa problemy” (choć nie bezpośrednio z powodu wyrażeń regularnych) :) calvinkrishy
2

że nie musisz tego robić. Próbować:

sed -rne 's/(dbservername)[[:blank:]]+\([[:alpha:]]+\)/\1 yyy/gip'

Powiązane pytania