Substitution in text file **without** regular expressions
Rise to the top 3% as a developer or hire one of them at Toptal: https://topt.al/25cXVn
--------------------------------------------------
Music by Eric Matyas
https://www.soundimage.org
Track title: Dreaming in Puzzles
--
Chapters
00:00 Substitution In Text File **Without** Regular Expressions
00:46 Accepted Answer Score 20
01:24 Answer 2 Score 4
01:37 Answer 3 Score 22
02:11 Answer 4 Score 7
02:53 Thank you
--
Full question
https://superuser.com/questions/422459/s...
--
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'