Search & replace inside files including subdirectories / Linux + Mac OS X

Veröffentlicht von

Für Suchen und Ersetzen innerhalb von Dateien auf der gesamten gewählten Ordnerstruktur – also einschließlich Unterordner in der Linux Shell bzw. dem SSH Terminal. Getestet unter CentOS 6 / Redhat Enterprise Linux.

Syntax for Mac OS is slightly different and also listed here.
Similar search entries Recursive search and replace within files including sub-directories.

Shows line-numbers at the result / Zeigt die Zeilennummern beim Suchergebnis
Linux: find . -iname '*.php' | xargs grep -H -n 'http://'
OS X: grep 'http://' -R .

Shows all php files with http:// in it’s content.

Search AND replace inside those file:
Linux: find . -type f -exec sed -i 's/somethingold/somethingnew/' {} ;
OS X:  find . -type f -exec sed -i '' s/.local/.dev/ {} +

Da der sed befehl mit -i einen regex String erwartet, müssen in diesem Beispiel die Slashes // natürlich mit Backslash escaped werden.

Search and replace inside specific file naes only:
Linux: find . -type f -name '*.conf' -exec sed -i 's/foo/bar/' {} ;
OS X:  find . -type f -name '*.conf' -exec sed -i '' s/.local/.dev/ {} +

Update: A slightly advanced search and replace variance, with excluding files (Linux + Mac):

#!/bin/bash
# search and remove a string from files
BASE_DIR=`dirname $0`
find $BASE_DIR/../../test/unit/spec/ -type f -iname '*.js' ! -name "some-excluded-file.js" -exec sed -i '' -e 's/filteredTests//' {} \;

Eine weitere Variante – das command line tool rpl:

Redhat / CentOS:
yum install rpl
rpl.noarch : Intelligent recursive search/replace utility
Dieses habe ich bei mir im epel Repository gefunden und ist mit seinen 30k auch schön schlank.
Debian:
apt-get install rpl

RPL Usage:
rpl -x'.php' -x'.html' -pR "oldstring" "newstring" *
Dieser Befehl sucht innerhalb .php und .html Dateien nach oldstring und ersetzt mit newstring – recursive in den Unterordnern.

In meinem Falle habe ich dies noch erweitert um mehr ausgabe (v) und einen Testlauf (s) zu haben, dabei Groß und Kleinschreibung zu ignorieren (i) und die Modifikationszeit beizubehalten, da ich trotz Umstellung auf https wissen möchte, wann die Dateien inhaltlich das letzte Mal geändert wurden:
rpl -idpRv -x'.php' 'https://www.eden' 'https://www.eden' *

rpl Befehle (help):
usage: rpl [options] old_string new_string target_file(s)

options:
–version show program’s version number and exit
-h, –help show this help message and exit
-L, –license show the software license
-x SUFFIX specify file suffix to match
-i, –ignore-case do a case insensitive match
-w, –whole-words whole words (old_string matches on word boundaries only)
-b, –backup make a backup before overwriting files
-q, –quiet quiet mode
-v, –verbose verbose mode
-s, –dry-run simulation mode
-R, –recursive recurse into subdirectories
-e, –escape expand escapes in old_string and new_string
-p, –prompt prompt before modifying each file
-f, –force ignore errors when trying to preserve permissions
-d, –keep-times keep the modification times on modified files
-t, –use-tmpdir use $TMPDIR for storing temporary files
-a, –all do not ignore files and directories starting with .