Mam projekt Visual Studio, który jest rozwijany lokalnie. Pliki kodu należy wdrożyć na serwerze zdalnym. Jedynym problemem jest to, że adresy URL, które zawierają, są zakodowane na stałe.
Projekt zawiera adresy URL, takie jak ? Page = one . Aby link był ważny na serwerze, musi to być / page / one .
Zdecydowałem się zastąpić wszystkie adresy URL w moich plikach kodowych sedem przed wdrożeniem, ale utknąłem na ukośnikach.
Wiem, że to nie jest ładne rozwiązanie, ale to proste zaoszczędziłoby mi dużo czasu. Całkowita liczba ciągów, które muszę wymienić, jest mniejsza niż 10. Całkowita liczba plików do sprawdzenia to ~ 30.
Przykład opisujący moją sytuację znajduje się poniżej:
Polecenie, którego używam:
sed -f replace.txt < a.txt > b.txt
replace.txt, który zawiera wszystkie ciągi:
s/?page=one&/pageone/g
s/?page=two&/pagetwo/g
s/?page=three&/pagethree/g
a.txt:
?page=one&
?page=two&
?page=three&
Zawartość b.txt po uruchomieniu komendy sed:
pageone
pagetwo
pagethree
Co chcę, aby plik b.txt zawierał:
/page/one
/page/two
/page/three
Odpowiedzi:
Najprostszym sposobem byłoby użycie innego separatora w wierszach wyszukiwania / zamiany, np .:
Możesz użyć dowolnego znaku jako separatora, który nie jest częścią żadnego ciągu. Lub możesz uciec z ukośnikiem odwrotnym:
Który zastąpiłby
/
zfoo
. Chciałbyś użyć odwrotnego ukośnika ze znakiem ucieczki w przypadkach, gdy nie wiesz, jakie znaki mogą wystąpić w łańcuchach zastępczych (na przykład jeśli są to zmienne powłoki).źródło
sed
polecenie regex jest umieszczone w podwójnych cudzysłowach. Nie użyłem ich w mojej odpowiedzi, ponieważ nie pokazałem całejsed
linii poleceń, ale tylkosed
ciąg polecenia regex, tak jak zrobił to OP. Jeśli umieścisz go w pliku, tak jak zrobił to OP, nie potrzebujesz cudzysłowów.sed
polecenie w skrypcie powłoki, może być potrzebnych więcej odwrotnych ukośników (każdy lewy ukośnik musi być ponownie odwrócony).s
Polecenia można użyć dowolnego znaku jako separatora; dowolny znak pojawiający się po znakus
. Zostałem wychowany, aby używać#
. Tak jak to:źródło
Bardzo przydatnym, ale mniej znanym faktem dotyczącym seda jest to, że znane
s/foo/bar/
polecenie może używać dowolnej interpunkcji, a nie tylko ukośników. Powszechną alternatywą jest tos@foo@bar@
, że staje się oczywiste, jak rozwiązać twój problem.źródło
dodaj \ przed znakami specjalnymi:
itp.
źródło
s/foo\/bar/foo_bar/
zadziała, ale/foo\/bar/foo_bar/
nie zadziała.W systemie, który tworzę, ciąg znaków do zastąpienia przez sed jest tekstem wejściowym od użytkownika, który jest przechowywany w zmiennej i przekazywany do seda.
Jak wspomniano wcześniej w tym poście, jeśli ciąg zawarty w bloku poleceń sed zawiera rzeczywisty separator używany przez sed - to sed kończy się z powodu błędu składniowego. Rozważmy następujący przykład:
To działa:
To się psuje:
Zastąpienie domyślnego separatora nie jest w moim przypadku solidnym rozwiązaniem, ponieważ nie chciałem ograniczać użytkownikowi możliwości wprowadzania określonych znaków używanych przez seda jako separatora (np. „/”).
Jednak zastąpienie dowolnego wystąpienia separatora w ciągu wejściowym rozwiązałoby problem. Rozważ poniższe rozwiązanie polegające na systematycznym unikaniu znaku ogranicznika w ciągu wejściowym przed przeanalizowaniem go przez sed. Takie ucieczki można zaimplementować jako zamiennik przy użyciu samego seda, to zastąpienie jest bezpieczne, nawet jeśli ciąg wejściowy zawiera ogranicznik - dzieje się tak, ponieważ ciąg wejściowy nie jest częścią bloku poleceń sed:
Przekonwertowałem to na funkcję, która ma być używana przez różne skrypty:
źródło
VALUE="01\\\/01\\\/2018"
ta linia powinna działać dla Twoich 3 przykładów:
-r
, aby zaoszczędzić trochę ucieczkę.przetestuj na swoim przykładzie (a.txt):
źródło
replace.txt
Powinien byćźródło
Świetna odpowiedź od Anonimowego. \ rozwiązałem mój problem, gdy próbowałem uniknąć cudzysłowów w łańcuchach HTML.
Więc jeśli używasz seda do zwrócenia niektórych szablonów HTML (na serwerze), użyj podwójnego odwrotnego ukośnika zamiast pojedynczego:
źródło
sed
jest s TREAM ed itor , w których można użyć|
(rury) do wysyłania standardowych strumieni (stdin i stdout konkretnie) przezsed
i zmieniać je programowo w locie, co czyni go przydatnym narzędziem w tradycji filozofii Unix; ale może również edytować pliki bezpośrednio, używając-i
parametru wymienionego poniżej.Weź pod uwagę następujące kwestie :
s/
stosuje się S ubstitute znaleziony ekspresjifew
zasd
:/g
oznacza „globalny”, co oznacza, że należy to robić dla całej linii. Jeśli opuścisz/g
(zs/few/asd/
, zawsze muszą być trzy ukośniki bez względu na wszystko) ifew
pojawi się dwa razy w tym samym wierszu, tylko pierwszyfew
zostanie zmieniony naasd
:Jest to przydatne w niektórych okolicznościach, takich jak zmiana znaków specjalnych na początku wierszy (na przykład zastąpienie symboli większości używanych przez niektórych ludzi do cytowania poprzedniego materiału w wątkach e-maili za pomocą poziomej tabulatora, pozostawiając cytowaną nierówność algebraiczną w dalszej części wiersza nietknięty), ale w Twoim przykładzie, w którym określasz, że gdziekolwiek
few
występuje, należy go wymienić, upewnij się, że masz to/g
.Następujące dwie opcje (flagi) są połączone w jedną
-ie
:-i
Opcja ta służy do edycji I n miejsce na plikhello.txt
.-e
Opcja wskazuje e Xpression / polecenie Uruchom, w tym przypadkus/
.Uwaga: ważne jest,
-i -e
aby wyszukiwać / zamieniać. Jeśli to zrobisz-ie
, utworzysz kopię zapasową każdego pliku z dołączoną literą „e”.źródło
Prostszą alternatywą jest użycie AWK w tej odpowiedzi :
awk '$0="prefix"$0' file > new_file
źródło