Substitution in text file **without** regular expressions
--
Music by Eric Matyas
https://www.soundimage.org
Track title: Puzzle Meditation
--
Chapters
00:00 Question
01:04 Accepted answer (Score 19)
02:01 Answer 2 (Score 21)
02:47 Answer 3 (Score 13)
03:23 Answer 4 (Score 7)
04:20 Thank you
--
Full question
https://superuser.com/questions/422459/s...
Accepted answer links:
[regular expression]: http://en.wikipedia.org/wiki/Regular_exp...
[Escape a string for sed search pattern]: https://stackoverflow.com/a/2705678/7048...
[here]: https://superuser.com/questions/422459/s...
[here]: https://stackoverflow.com/a/1048144/7048...
Answer 3 links:
https://linux.die.net/man/1/replace
Answer 4 links:
https://stackoverflow.com/questions/4075...
--
Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...
--
Tags
#bash #regex #sed #textediting
#avk47
ANSWER 1
Score 22
export FIND='find this'
export REPLACE='replace with this'
ruby -p -i -e "gsub(ENV['FIND'], ENV['REPLACE'])" path/to/file
This is the only 100% safe solution here, because:
- It's a static substition, not a regexp, no need to escape anything (thus, superior to using
sed) - It won't break if your string contains
}char (thus, superior to a submitted Perl solution) - It won't break with any character, because
ENV['FIND']is used, not$FIND. With$FINDor your text inlined in Ruby code, you could hit a syntax error if your string contained an unescaped'.
ACCEPTED ANSWER
Score 20
When you don't need the power of regular expressions, don't use it. That is fine.
But, this is not really a regular expression.
sed 's|literal_pattern|replacement_string|g'
So, if / is your problem, use | and you don't need to escape the former.
PS: About the comments, also see this Stackoverflow answer on Escape a string for sed search pattern.
Update: If you are fine using Perl try it with \Q and \E like this,
perl -pe 's|\Qliteral_pattern\E|replacement_string|g'
@RedGrittyBrick has also suggested a similar trick with stronger Perl syntax in a comment here or here
ANSWER 3
Score 7
You can do it converting the patterns to their escaped form automatically. Like this:
keyword_raw=$'1\n2\n3'
keyword_regexp="$(printf '%s' "$keyword_raw" | sed -e 's/[]\/$*.^|[]/\\&/g' | sed ':a;N;$!ba;s,\n,\\n,g')"
# keyword_regexp is now '1\/2\/3'
replacement_raw=$'2\n3\n4'
replacement_regexp="$(printf '%s' "$replacement_raw" | sed -e 's/[\/&]/\\&/g' | sed ':a;N;$!ba;s,\n,\\n,g')"
# replacement_regexp is now '2\/3\/4'
echo $'a/b/c/1\n2\n3/d/e/f' | sed -e "s/$keyword_regexp/$replacement_regexp/"
# the last command will print 'a/b/c/2\n3\n4/d/e/f'
Credits for this solutions goes here: https://stackoverflow.com/questions/407523/escape-a-string-for-a-sed-replace-pattern
Note1: this only works for non-empty keywords. Empty keywords are not accepted by sed (sed -e 's//replacement/').
Note2: unfortunately, I don't know a popular tool that would NOT use regexp-s to solve the problem. You can write such a tool in Rust or C, but it's not there by default.
ANSWER 4
Score 4
You could also use perl's \Q mechanism to "quote (disable) pattern metacharacters"
perl -pe 'BEGIN {$text = q{your */text/?goes"here"}} s/\Q$text\E/replacement/g'