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$FIND
or 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'