Einen Textabschnitt in mehreren Files gleichzeitig ersetzen

Ein Beispiel: ein Programm, das ursprünglich für Windows geschrieben wurde, beinhaltet in den #include-Direktiven gelegentlich auch die (relativen) Pfad-Angaben, die unter Windows i.d.R. Backslashes '\' beinhalten. Bei der Portierung auf Unix führt das zu Problemen.

Um nicht per Hand hunderte Quelltexte anpassen zu müssen, hier ist ein Skript, welches dises Vorhaben automatisch erledigt.

Das Skript sucht im aktuellen Verzeichnis und rekursiv in allen Unterverzeichnissen in allen .h-, .c- und .cpp-Files Zeilen, die #include beinhalten und ersetzt (nur in diesen Zeilen) alle Vorkomnisse von '\' durch '/'. Vor dem Editieren legt das Skript eine Sicherungskopie des betroffenen Files an.

Danach sehen etwa die Zeilen:

#include "..\..\defines_global.h"

…wie folgt aus:

#include "../../defines_global.h"

Das einfache Find+Replace ist dafür eher ungeeignet, weil ein '\' häufig auch an vielen anderen Stellen vorkommt, wie z.B. in '\n' oder '\0', etc.

Skript:

juergen@develop:/prj/beispiel/cpp_projekt> cat backslash2slash.sh
# Replaces all occurrences of '\' by '/' in the directories in the "#include"-lines.
 
# For the backups:
SAVE_DATUM=`date +%Y%m%d`
# Counter of replaced files:
COUNTER_FILES=0
 
#echo SAVE_DATUM    = ${SAVE_DATUM}
#echo COUNTER_FILES = ${COUNTER_FILES}
 
for FILE in `find . -name "*.h" -o -name "*.c" -o -name "*.cpp"`
do
#       echo Test of file: ${FILE}
        grep '#include' ${FILE} | grep '\\'  > /dev/null
        if [ $? -eq 0 ]
        then
                echo Replacing: ${FILE}
                cp ${FILE} ${FILE}.${SAVE_DATUM}
                sed '/#include/s/\\/\//g' ${FILE} > ${FILE}.changed
                mv ${FILE}.changed ${FILE}
                COUNTER_FILES=$((${COUNTER_FILES}+1))
        fi
done
 
echo
echo ${COUNTER_FILES} Files are replaced.
 
# EOF
juergen@develop:/prj/beispiel/cpp_projekt>

Stand: 11.12.2015

EOF