Nach diesem Script habe ich mich in den Anfängen meiner Linux-Zeit[^1) dumm und dämlich gesucht. Aus Nostalgie-Gründen (und vielleicht braucht man es ja doch noch mal, paste ich es hier nochmal rein. Alles andere kommt inzwischen ins git.
Aufgabe
Es ersetzt in allen Dateien der angegebenen Verzeichnisse, das per Parameter angegebene Suchmuster.
Gebraucht habe ich es mal für meinen HTML-Seiten wo ich "EUR" durch "€" ersetzen wollte.
Anwendung
1usage: gsed sed-command [dir ...]
sed-command entspricht dabei den normalen sed Parameter. Siehe man-Page.
Einige Anwendungsbeispiele:
1gsub s/EUR/\\\&euro\;/g # ====> EUR => €
2gsub s/\Ä/\\\Ä\;/g # ====> Ä => Ä (Groß- Kleinschreibung beachten !)
3gsub s/\Ä/\\\Ä\;/gi # ====> Ä => Ä (Groß- Kleinschreibung egal !)
4gsub s/\
5\<\\\/td\>/\<\\\/td\>/g # =====> <br></td> => </td>
6gsub s/http\:\\/\\/www./..\\/img/g # ====> http://www. => /img
Prinzip:
s/raus/rein/g
Weiterer Tipp
Und wenn das ersetzen nicht klappt ruhig mal öfters ein \ setzen, wie bei:
\\\&\\/
Quell-Code
1 #!/bin/sh
2 #
3 # Global sed on all files contained in a list of directories.
4 # The command
5 # gsub cmd dir1 dir2 ...
6 # will do
7
8 # sed -e cmd
9 # on each file found in dir1, dir2, ...
10 #
11 # If a file is changed, a backup copy is created.
12 # Files .*.swp and CVS directories are skipped.
13
14
15 usage() {
16 echo "usage: gsed sed-command [dir ...]" >& 2
17 exit 1
18 }
19
20 tmp=/var/tmp/gsub.$$
21
22
23 trap "rm -f $tmp" 0 1 2 3 15
24
25 if [ $# -lt 1 ]; then
26 usage
27 fi
28
29
30 cmd="$1"
31
32 shift
33
34 if [ $# = 0 ]; then
35 set .
36 fi
37
38
39 find $* -name CVS -prune -o \( -type f ! -name '*~' ! -name '.*.swp' -print \) |
40 while read file; do
41 sed -e "$cmd" "$file" > "$tmp"
42 if cmp -s "$file" "$tmp"; then
43 :
44
45 else
46 echo "$file: patched" >& 2
47 mv "$file" "$file~"
48 cp "$tmp" "$file"
49 fi
50
51 done
Dank
Dank an Matthias Kilian von der LUG-Braunschweig :!:
Original-Ton aus seiner Mail:
Bitte nach Bedarf tunen. [Ja, ich weiß, dass es böse ist, das temporäre Verzeichnis fest zu verdrahten. Wer das nicht mag, kann ja zusätzliche TMPDIR auswerten.]
Das Script ist sogar so nett, nur Dateien, die sich wirklich geändert haben, zu überschreiben, bei unmodifizierten Dateien bleibt also die Modificationtime unverändert. Außerdem wird bei modifizierten Dateien eine Backupdatei angelegt.
Würde ich es heute noch mal schreiben, dann würde ich aber wohl statt sed(1) den ed(1) nehmen, um mir den ganzen Kram mit temporären Dateien zu ersparen.