Using a Simple Python Script
Most systems have python ready to go these days. So here's a simple script that'll work for ya:
# replace.py
# USAGE: python replace.py bad-word good-word target-file.txt
#
import sys
search_term = sys.argv[1]
replace_term = sys.argv[2]
target_file = sys.argv[3]
with open(target_file, 'r') as file:
content = file.read()
content = content.replace(sys.argv[1], sys.argv[2])
with open(target_file, 'w') as file:
file.write(content)
One Caveat: This works great if your good/bad words are already in system/environment variables.
Just make sure you use double-quotes to wrap the variables when passing to the script.
For example:
python replace.py "$BAD_WORD" "$GOOD_WORD" target-file.txt
However, these will not work:
# This breaks on $ or " characters
BAD_WORD="your-artibrary-string"
# This breaks on ' characters
BAD_WORD='your-artibrary-string'
# This breaks on spaces plus a variety of characters
BAD_WORD=your-artibrary-string
Handling Arbitrary Literal Characters
1. Write the Chars to Disk
If I need to provide a arbitrary literal value to a script (skipping any escaping), I generally write it to disk using this method:
head -c -1 << 'CRAZY_LONG_EOF_MARKER' | tee /path/to/file > /dev/null
arbitrary-one-line-string
CRAZY_LONG_EOF_MARKER
... where:
- We're employing the Here Document mechanism to write literal text
- We're using
head
and tee
to delete the trailing newline that Here Docs create
- We're preventing evalution of variables inside the Here Doc by quoting the EOL marker string
Here's a quick demo with tricky chars:
head -c -1 << 'CRAZY_LONG_EOF_MARKER' | tee /path/to/file > /dev/null
1"2<3>4&5'6$7 # 8
CRAZY_LONG_EOF_MARKER
2. Use Modified Python Script
Here's an updated script that reads from word files:
# replace.py
# USAGE: python replace.py bad-word.txt good-word.txt target-file.txt
#
import sys
search_term_file = sys.argv[1]
replace_term_file = sys.argv[2]
target_file = sys.argv[3]
print [search_term_file, replace_term_file, target_file]
with open(search_term_file, 'r') as file:
search_term = file.read()
with open(replace_term_file, 'r') as file:
replace_term = file.read()
with open(target_file, 'r') as file:
content = file.read()
print [search_term, replace_term]
content = content.replace(search_term, replace_term)
with open(target_file, 'w') as file:
file.write(content)
related: https://stackoverflow.com/questions/29613304/is-it-possible-to-escape-regex-metacharacters-reliably-with-sed
– Ciro Santilli 新疆改造中心法轮功六四事件 – 2018-03-28T13:07:24.997Related. tl;dr: use
tr
,sed
withy/
. Take a look tosponge
. – Pablo A – 2020-02-11T15:44:31.227Necessary to do it through bash? A simplistic solution would be to open in Word and do a
find and replace all
– Akash – 2012-05-09T15:04:04.97718@akash Because systems that have
bash
always ship with Microsoft Word? ;) No.. Just kidding. The OP might want to do this on a remote machine or for a batch of files though. – slhck – 2012-05-09T15:07:03.890@slhck :) Well, I guess gedit should have a similar option – Akash – 2012-05-09T15:09:33.487
An option would be to somehow correctly escape everything before passing it to
sed
, which is probably a futile effort considering all the switches and platform differences. – l0b0 – 2012-05-09T15:11:48.177