Collection of great links to sed tutorials, docs, types, etc.
If all in the same subdirectory, ...
$ sed -i 's/text/replacement/g' file1 file2 ... filen
Otherwise, ...
# grep -l <string> <filenames> | xargs sed -i 's/<string>/<replacement>/'
(Yeah, that doesn't work despite claims.) Here's how I do it. My example is replacing "java-junit-test-files" everywhere with TestUtilities.JAVA_UNIT_TEST_FILES:
# find . -name '*.java' -exec sed -i 's/\"java-junit-test-files\"/TestUtilities.JAVA_UNIT_TEST_FILES/' {} \;
Option -l (that’s not the number, but the lower-case letter) causes filenames to be output that contain <string>. xargs takes these and feeds them one at a time to sed which replaces the first occurrance of <string> in <replacement>. Option -i tells sed to work within the file on which it’s called, renaming the temporary file sed creates back to the original filename when finished (no temporary file is left over after the deed). For example, let’s replace “[email protected]” in all the text files in the current directory with “[email protected]”:
# grep -l [email protected] <filenames> | xargs sed -i 's/[email protected]/[email protected]/'
Sometimes, you can play with a command and accomplish a lot, get it just perfect, but, inexplicably, it won't work in the larger script. The single quotes impede the expansion of the shell variables ($HTTP_PORT, etc.). I'm used to single-quoting the match/replace string. If sed doesn't work in your script, try removing the quotes to see if that doesn't fix it.
Observe the two scripts below, one of which works and the other does not. It's the second set that finally worked for me though I had to back-tick the whole thing to get the redirection to work.
These sed statements here worked in isolation (command line trials), but not inserted in the context of a larger script:
#!/bin/sh . . . DEFAULT_HTTP_PORT=8080 HTTP_PORT=48080 DEFAULT_AJP_PORT=8009 AJP_PORT=48009 . . . rm -f server.xml.old sed 's/$DEFAULT_HTTP_PORT/$HTTP_PORT/g' server.xml > server.xml.1 sed 's/$DEFAULT_AJP_PORT/$AJP_PORT/g' server.xml.1 > server.xml.2 mv server.xml server.xml.old cp server.xml.2 server.xml rm server.xml.1 server.xml.2 . . .
This set worked. All I had to do was remove the single quotes.
#!/bin/sh . . . DEFAULT_HTTP_PORT=8080 HTTP_PORT=48080 DEFAULT_AJP_PORT=8009 AJP_PORT=48009 . . . rm -f server.xml.old `sed s/$DEFAULT_HTTP_PORT/$HTTP_PORT/g server.xml > server.xml.1` `sed s/$DEFAULT_AJP_PORT/$AJP_PORT/g server.xml.1 > server.xml.2` mv server.xml server.xml.old cp server.xml.2 server.xml rm server.xml.1 server.xml.2 . . .
In this command, there is a file whose contents come out of variable DATA, input to sed and, in those contents, the line
pidfile /usr/local/var/run/redis.pid
is to be replaced by
pidfile $PIDFILE
that is, the usual Redis file is to be replaced by the new path specified in variable PIDFILE. (The file being modified is a Redis configuration file.)
1. Embed a path: the path contains slashes, which are the typical delimiter in a sed command. Simply replace sed's delimiter with another character, here @. Maybe a better character would be the vertical bar.
2. Often the single quote is used to bracket a sed search/replace string. In order to get proper expansion of the variable, PIDFILE, double quotes must be used.
3. The <<< operator directs input from variable DATA.
Here's the script line:
OUTPUT=$(sed "s@pidfile /usr/local/var/run/redis.pid@pidfile ${PIDFILE}@" <<< "${DATA}")