Muszę zastąpić część tekstu w pliku tekstowym zamiennikiem. Zwykle robiłbym coś takiego
sed -i 's/text/replacement/g' path/to/the/file
Problem polega na tym, że zarówno text
i replacement
są złożone ciągi zawierające kreski, ukośniki, blackslashes, cytaty i tak dalej. Jeśli ucieknę, wszystkie niezbędne postacie w środku text
stają się szybko nieczytelne. Z drugiej strony nie potrzebuję mocy wyrażeń regularnych: wystarczy dosłownie zastąpić tekst.
Czy istnieje sposób na zastąpienie tekstu bez użycia wyrażeń regularnych z jakimś poleceniem bash?
Pisanie skryptu, który to robi, byłoby raczej trywialne, ale sądzę, że coś już powinno istnieć.
bash
regex
sed
text-editing
Andrea
źródło
źródło
find and replace all
bash
zawsze są dostarczane z Microsoft Word? ;) Nie, tylko żartuję. OP może chcieć to zrobić na zdalnym komputerze lub w przypadku partii plików.sed
, co jest prawdopodobnie daremnym wysiłkiem, biorąc pod uwagę wszystkie przełączniki i różnice platform.Odpowiedzi:
Kiedy nie potrzebujesz mocy wyrażeń regularnych, nie używaj jej. W porządku.
Ale tak naprawdę nie jest to wyrażenie regularne .
sed 's|literal_pattern|replacement_string|g'
Jeśli więc
/
masz problem, skorzystaj z niego|
i nie musisz uciekać przed pierwszym.ps: o komentarzach, zobacz także odpowiedź Stackoverflow na temat Escape a string for sed search pattern .
Aktualizacja: Jeśli nie masz nic przeciwko używaniu Perla, wypróbuj go
\Q
i\E
tak,perl -pe 's|\Qliteral_pattern\E|replacement_string|g'
RedGrittyBrick
sugeruje podobną sztuczkę z silniejszą składnią Perla w komentarzu tutajźródło
s|||
is///
polega na tym, że postać oddzielająca jest inna i dlatego jedna postać nie musi uciekać. Równie dobrze możeszs###
. Prawdziwy problem polega na tym, że OP nie chce się martwić o ucieczkę od treściliteral_pattern
(co nie jest wcale dosłowne i zostanie zinterpretowane jako wyrażenie regularne).1234.*aaa
swoim rozwiązaniu, pasuje ono znacznie bardziej niż zamierzone1234\.\*aaa
.Jest to jedyne w 100% bezpieczne rozwiązanie, ponieważ:
sed
)}
char (czyli lepszy niż przesłane rozwiązanie Perla)ENV['FIND']
jest używana, a nie$FIND
. Z$FIND
lub w tekście wstawionym w kodzie Ruby, możesz trafić w błąd składniowy, jeśli ciąg zawiera nieskalowany'
.źródło
export FIND='find this; export REPLACE='replace with this';
w moim skrypcie bash, tak żeENV['FIND']
iENV['replace']
miał oczekiwaną wartość. Zastępowałem niektóre naprawdę długie zaszyfrowane ciągi w pliku. To był tylko bilet.replace
Komenda będzie to zrobić.https://linux.die.net/man/1/replace
Zmień miejsce:
Do standardowego:
Przykład:
replace
Polecenie pochodzi z MySQL lub MariaDB.źródło
Możesz także użyć
\Q
mechanizmu perla do „ cytowania (wyłączania) metaznaków wzorca ”źródło
perl -pe 's(\Qyour */text/?goes"here")(replacement)' file
sprawdź mój skrypt Perla. robi dokładnie to, czego potrzebujesz, bez niejawnego lub jawnego użycia wyrażeń regularnych:
https://github.com/Samer-Al-iraqi/Linux-str_replace
bardzo przydatny, prawda? Musiałem się tego nauczyć. ponieważ naprawdę tego potrzebuję.
źródło
Możesz to zrobić, unikając swoich wzorów. Lubię to:
Kredyty dla tych rozwiązań można znaleźć tutaj: https://stackoverflow.com/questions/407523/escape-a-string-for-a-sed-replace-pattern
Uwaga 1: działa to tylko w przypadku niepustych słów kluczowych. Puste słowa kluczowe nie są akceptowane przez sed (
sed -e 's//replacement/'
).Uwaga 2: niestety nie znam popularnego narzędzia, które NIE użyłoby wyrażeń regularnych do rozwiązania problemu. Możesz napisać takie narzędzie w Rust lub C, ale domyślnie go nie ma.
źródło
Zebrałem kilka innych odpowiedzi i wymyśliłem to:
źródło
\n
. Jakieś rozwiązanie?Możesz użyć ph_'s str_replace :
Uwaga: Jednak nadal będziesz musiał unikać pojedynczych
'
i podwójnych cudzysłowów"
.źródło
Odpowiednik Node.JS @Nowaker:
źródło
Oto jeszcze jeden „prawie” działający sposób.
Użyj vi lub vim.
Utwórz plik tekstowy z podstawieniem:
następnie uruchom vi lub vim z wiersza poleceń:
:% sno to polecenie vi do wyszukiwania i zastępowania bez magii.
/ jest moim wybranym separatorem.
: x zapisuje i wychodzi vi.
Musisz uciec z ukośników odwrotnych „\” Forwardlash ”/„ można zastąpić np. Znakiem zapytania ”? lub coś innego, czego nie ma w wyszukiwaniu lub zamień ciąg, potok „|” nie działało dla mnie tys.
ref: https://stackoverflow.com/questions/6254820/perform-a-non-regex-search-replace-in-vim https://vim.fandom.com/wiki/Search_without_need_to_escape_slash http://linuxcommand.org/ lc3_man_pages / vim1.html
źródło