string_replacer
Repeatedly replace text in a file without disturbing the rest of the file.
Use
$ string_replacer PATH STRING [REPLACEMENT_ID] [AFTER_LINE]
For example:
$ echo "hello" > test.txt
$ cat test.txt
hello
$ string_replacer test.txt "Don't forget to say \"hello world\"" "Just a reminder"
$ cat test.txt
hello
# START StringReplacer Just a reminder -- DO NOT MODIFY
Don't forget to say "hello world"
# END StringReplacer Just a reminder -- DO NOT MODIFY
Now I swap it out by using the same REPLACEMENT_ID
…
$ string_replacer test.txt "YOU ARE STILL FORGETTING to say \"hello world\"" "Just a reminder"
$ cat test.txt
hello
# START StringReplacer Just a reminder -- DO NOT MODIFY
YOU ARE STILL FORGETTING to say "hello world"
# END StringReplacer Just a reminder -- DO NOT MODIFY
And finally, to demonstrate that REPLACEMENT_ID
is case-sensitive…
$ string_replacer test.txt "Nevermind" "Just a Reminder"
$ cat test.txt
hello
# START StringReplacer Just a reminder -- DO NOT MODIFY
YOU ARE STILL FORGETTING to say "hello world"
# END StringReplacer Just a reminder -- DO NOT MODIFY
# START StringReplacer Just a Reminder -- DO NOT MODIFY
Nevermind
# END StringReplacer Just a Reminder -- DO NOT MODIFY
If you don’t specify REPLACEMENT_ID
, it will default to “1.”
Real-world usage
brighterplanet.com uses it to unmask the memcached 1.4.4 package on engineyard.com AppCloud (i.e. Amazon EC2) instances.
We have this in our before_restart.rb hook:
###############################################################
# make sure we have string_replacer installed at the system level
###############################################################
sudo 'gem install string_replacer --no-rdoc --no-ri'
###############################################################
# install memcached 1.4.4, which is not available by default
###############################################################
memcached_server_version = '1.4.4'
unless `/usr/bin/memcached -h`.include?(memcached_server_version)
sudo "/usr/bin/string_replacer /etc/portage/package.keywords/local \"=net-misc/memcached-#{memcached_server_version}\" \"make sure memcached #{memcached_server_version} is available\""
sudo "emerge net-misc/memcached"
end
sudo "cp #{release_path}/deploy/memcached/memcached.#{node[:environment][:name]} /etc/conf.d/memcached"
Before:
$ cat /etc/portage/package.keywords/local
=dev-lang/ruby-1.8.7_p174
After:
$ cat /etc/portage/package.keywords/local
=dev-lang/ruby-1.8.7_p174
# START StringReplacer make sure memcached 1.4.4 is available -- DO NOT MODIFY
=net-misc/memcached-1.4.4
# END StringReplacer make sure memcached 1.4.4 is available -- DO NOT MODIFY
Obvious flaws
-
assumes whitespace is ignored
-
assumes # means comment
-
no idea how it would work on big files
-
there is probably a unix program that has done this since the 1970s
Copyright
Copyright © 2010 Seamus Abshere. See LICENSE for details.