W moim skrypcie bash mam zewnętrzny (otrzymany od użytkownika) ciąg znaków, którego powinienem użyć we wzorcu sed.
REPLACE="<funny characters here>"
sed "s/KEYWORD/$REPLACE/g"
Jak mogę uciec od $REPLACE
łańcucha, aby został bezpiecznie zaakceptowany sed
jako dosłowny zamiennik?
UWAGA: To KEYWORD
głupie podłoże bez pasujących elementów itp. Nie jest dostarczane przez użytkownika.
outputvar="${inputvar//"$txt2replace"/"$txt2replacewith"}".
Odpowiedzi:
Ostrzeżenie : nie uwzględnia to nowych linii. Aby uzyskać bardziej szczegółową odpowiedź, zobacz to pytanie SO . (Dzięki, Ed Morton i Niklas Peter)
Pamiętaj, że ucieczka od wszystkiego to zły pomysł. Sed potrzebuje wielu znaków cytowania, aby mieć się ich specjalne znaczenie. Na przykład, jeśli wybierzesz cyfrę w ciągu zastępującym, zmieni się ona w odniesienie wsteczne.
Jak powiedział Ben Blank, tylko trzy znaki muszą być poprzedzone znakiem zastępującym (same znaki ucieczki, ukośnik dla końca instrukcji i & dla zamiany wszystkich):
Jeśli kiedykolwiek będziesz musiał uciec z
KEYWORD
łańcucha, potrzebujesz tego:I mogą być używane przez:
Pamiętaj, że jeśli używasz znaku innego niż
/
separator, musisz zastąpić ukośnik w wyrażeniach powyżej używanym znakiem. Wyjaśnienie znajduje się w komentarzu PeterJCLaw.Edytowane: Z powodu niektórych przypadków narożników, których wcześniej nie uwzględniono, powyższe polecenia zmieniły się kilka razy. Sprawdź historię edycji, aby uzyskać szczegółowe informacje.
źródło
KEYWORD
, w GNU sed , są jeszcze 2 znaki^
,$
nie wymienione powyżej:s/[]\/$*.^|[]/\\&/g
A='foo"bar' echo $A | sed s/$A/baz/
w Podwójne cytaty są traktowane jak „foo” i „bar” wokół nichKomenda sed pozwala używać innych znaków zamiast
/
jako separatora:Podwójne cudzysłowy nie stanowią problemu.
źródło
.
co inaczej ma specjalne znaczenie. Zredagowałem twoją odpowiedź.sed '/CLIENTSCRIPT="foo"/a CLIENTSCRIPT2="hello"' file
zsed '|CLIENTSCRIPT="foo"|a CLIENTSCRIPT2="hello"' file
i to nie robi tego samego.s
Komenda (jak w zastępstwie) sed pozwala na użycie innych znaków zamiast / jako separatora. Byłaby to również odpowiedź na to, jak używać sed na adresie URL ze znakami ukośnika. Nie odpowiada na pytanie OP, jak uciec od łańcucha wprowadzonego przez użytkownika, który może zawierać /, \, ale także #, jeśli zdecydujesz się go użyć. A poza tym URI może zawierać #Jedynymi trzema dosłownymi znakami, które są traktowane specjalnie w klauzuli zastępującej, są
/
(aby zamknąć klauzulę),\
(aby uciec od znaków, referencje zwrotne i c.) Oraz&
(aby uwzględnić dopasowanie w zamianie). Dlatego wszystko, co musisz zrobić, to uciec od tych trzech znaków:Przykład:
źródło
Na podstawie wyrażeń regularnych Pianozaura stworzyłem funkcję bash, która unika zarówno słowa kluczowego, jak i zamiany.
Oto jak go używasz:
źródło
man echo
), powodując, że potok zachowuje się nieoczekiwanie, gdy twój argument$1
zaczyna się od myślnika. Zamiast tego możesz rozpocząć swoją fajkęprintf '%s\n' "$1"
.Trochę późno jest odpowiedzieć ... ale jest O wiele prostszy sposób, aby to zrobić. Wystarczy zmienić ogranicznik (tj. Znak oddzielający pola). Zamiast tego
s/foo/bar/
piszs|bar|foo
.Oto prosty sposób:
Wynikowy wynik jest pozbawiony tej paskudnej klauzuli DEFINER.
źródło
&
i `` wciąż trzeba uciec, podobnie jak separator, cokolwiek zostanie wybrane.$
w ciągu, który ma zostać zmieniony, i zachować znaczenie$
w ciągu zastępującym. powiedz, że chcę zmienić$XXX
na wartość zmiennej$YYY
,sed -i "s|\$XXX|$YYY|g" file
działa dobrze.Okazuje się, że zadajesz złe pytanie. Zadałem też złe pytanie. Przyczyną tego jest początek pierwszego zdania: „W mojej bacie skrypcie ...”.
Miałem to samo pytanie i popełniłem ten sam błąd. Jeśli używasz bash, nie musisz używać seda, aby zamieniać ciągi (i znacznie łatwiej jest korzystać z funkcji zamiany wbudowanej w bash).
Zamiast czegoś takiego jak na przykład:
możesz korzystać wyłącznie z funkcji bash:
źródło
$A
i$B
nie jest cytowany, ale tak nie jest. Cytaty wewnątrz${}
nie pasują do cytatów poza nim.var='has space'
) -OUTPUT=${INPUT//"$A"/"$B"}
jest bezpieczny.Użyj awk - jest czystszy:
źródło
awk
polega na tym, że nie ma nic podobnegosed -i
, co jest niezwykle przydatne w 99% przypadków.Oto przykład AWK, którego użyłem jakiś czas temu. Jest to AWK, który drukuje nowe AWKS. Ponieważ AWK i SED są podobne, może to być dobry szablon.
Wygląda na przesadne, ale jakoś ta kombinacja cytatów sprawia, że „drukowane są jako literały. Więc jeśli dobrze pamiętam, zmienne są otoczone takimi cytatami: „1 $”. Wypróbuj, daj mi znać, jak to działa z SED.
źródło
Mam ulepszenie w stosunku do funkcji sedeasy, która BĘDZIE łamana znakami specjalnymi, takimi jak tab.
Czym się różni?
$1
i$2
zawinięte w cudzysłów, aby uniknąć rozszerzenia powłoki i zachować tabulatory lub podwójne spacje.Dodatkowe potokowanie
| sed -e 's:\t:\\t:g'
(lubię:
jako token), które przekształca kartę\t
.źródło
Oto kody ucieczki, które znalazłem:
źródło
nie zapomnij o całej przyjemności związanej z ograniczeniem powłoki wokół „i”
więc (w ksh)
źródło
Jeśli chcesz zastąpić zmienną w poleceniu sed, po prostu usuń Przykład:
źródło
Jeśli zdarza się, że generujesz losowe hasło, które ma zostać przekazane w celu
sed
zastąpienia wzorca, wybierz ostrożność przy wyborze zestawu znaków w losowym ciągu. Jeśli wybierzesz hasło utworzone przez zakodowanie wartości jako base64, wówczas istnieje tylko znak, który jest możliwy zarówno w base64, jak i znak specjalny wesed
wzorcu zastępowania. Ten znak to „/” i można go łatwo usunąć z generowanego hasła:źródło
Łatwiejszym sposobem na to jest zbudowanie łańcucha przed użyciem i użycie go jako parametru dla
sed
źródło
REPLACE=/
dajesed: -e expression #1, char 12: unknown option to `s'