BASH SCRIPT: sed, awk oder perl?

Hallo

In *.C oder *.h Dateien möchte ich ein #include „“ nach dem letzen #include „“ oder nach dem ersten #define einfügen.

/\*
\*\* datei abc.h
\*/
#ifndef \_ABC\_
#define \_ABC\_

#include "xyz.h"
#include "uvw.h"
// Hier soll ein #include "dateiname" rein ...
...
#endif

/\*
\*\* datei def.h
\*/
#ifndef \_DEF\_
#define \_DEF\_

// ... oder hier soll ein #include "dateiname" rein
...
#endif

/\*
\*\* datei abc.C
\*/
#include abc.h
// ... oder hier soll ein #include "dateiname" rein

void fAbc(int pI)
{
 ...
}
...

Wie mache ich das? Was ist am Besten geignet dazu? sed, awk, perl oder gar was anderes?

Dank und Gruss
Olli

Eigentlich geht es darum, die add_macroh_include_to_file Funktion in folgendem Bash Script zu realisieren. Der Rest Funktioniert bestens. Das ganz dient dazu, um sehen ob Valgind immmer noch heulen tut … :wink:

Dank und Gruss
Olli

#!/bin/bash --init-file
#

#
# function add\_macro\_to\_macroh
#
function add\_macro\_to\_macroh()
{
 echo ''
 MACROH='/macro/macro.h'
 MACROH\_NEW=$MACROH.new

 checkout $MACROH \> /dev/null
 cat $MACROH | grep -v '#endif' \>& $MACROH\_NEW
 cat \>\> $MACROH\_NEW & /dev/null
 if [[$? != 0]]
 then
 echo 'error while compiling' $1
 add\_macroh\_include\_to\_file $1
 echo 'compile again' $1
 $COMPILE $1 \>& /dev/null
 if [[$? != 0]]
 then
 echo 'error while compiling' $1
 revert $1 \>& /dev/null
 echo 'reverted' $1
 else
 echo 'compilation successful for' $1 
 fi
 else
 echo 'compilation successful for' $1
 fi
}

#
# function replace\_and\_compile
#
function replace\_and\_compile()
{
 for arg in "$@"; do
 echo ''
 #
 # search and replace and save changes
 #
 echo 'sed "s/strcpy/STRCPY/g"' $arg '\>' $arg.new
 sed 's/strcpy/STRCPY/g' $arg \> $arg.new
 #
 # move changes back to original file
 #
 echo 'mv' $arg.new $arg
 mv $arg.new $arg
 #
 # remove \*.new file
 #
 echo 'rm -f' $arg.new $arg
 rm -f $arg.new
 #
 # compile file
 #
 compile\_file $arg
 done
}

#
# Start
#
echo ''
echo 'starting replacement of strcpy with STRCPY'

# set environment
source ~/.bashrc
setmyenv

# 
# add the macro to macroh.h
#
add\_macro\_to\_macroh

#
# make files editable, replace string and compile
#
echo ''
echo 'checkout files'
checkout $(find\_in\_file strcpy h C | grep -v \_gui) \>& /dev/null
echo ''
echo 'start replacement of strcpy with STRCPY and compile'
replace\_and\_compile $(find\_in\_file strcpy h C | grep -v \_gui)

#
# End
#
echo ''
echo 'done'
echo 'please replace strcpy manualy in reverted files'
echo 'please submit files if everything is okay'

#
# revert where STRCPY, for convenience only
#
# echo ''
# echo 'Revert where STRCPY'
# revert $(find\_in\_file STRCPY h C | grep -v \_gui) \>& /dev/null

#
# revert where strcpy, for convenience only
#
# echo ''
# echo 'Revert where strcpy'
# revert $(find\_in\_file strcpy h C | grep -v \_gui) \>& /dev/null

#
# Exit Shell
#
exit

Hallo olli,

In *.C oder *.h Dateien möchte ich ein #include
„“ nach dem letzen #include
„“ oder nach dem ersten #define
einfügen.

Nach dem letzten #Include ein #include „macroh.h“
einfügen und Backup machen (1-Zeiler):

$ perl -i.bak -0777 -pe '
my @p; /#include\s+"\w+\.\w+\"\n(?{push@p,pos})/g;
substr($\_,pop@p,0,qq{#include "macroh.h"\n})
' \*.C

Nach dem ersten #define das #include „macroh.h“
einfügen und auch Backup machen (auch 1-Zeiler):

$ perl -i.bak -0777 -pe '
s/(#define\s+.\*)\n/$1."\n#include \"macroh.h\""/me
' \*.h

Leider sind die „Zeilen“ etwas lang geraten :wink:
(Aber das Prinzip sollte klar sein …)

Grüße

CMБ

Vielen Dank, ich werde das probieren.

Gruss, Olli

Hallo olli,

werde das probieren.

Falls es sich um #include „dies.h“ __(leerzeichen)
bzw. um #include handel könnte, muss man
den ersten Oneliner etwas abwandeln:

$ perl -0777 -pe '
my @p;/#include\s+["]\s\*\n(?{push@p,pos})/g;
substr($\_,pop@p,0,qq{#include "macroh.h"\n})
' \*.C

Grüße

CMБ

Hallo

$ perl -0777 -pe ’

natürlich:

$ perl -i.bak -0777 -pe '
...

denn Du willst ja das File auch
verändern …

Grüße

CMБ

1 Like

Okay, vielen Dank. Leider reicht es mir bis Montag nicht mehr ins Büro. Bin echt froh um solche Tipps. Ich melde mich wieder.

Wünsche Dir ein schönes Wochenende.

Gruss
Olli

Guten Morgen

Ja, das Perl-Script funktioniert. Juhuuuu … :wink: Danke!

Leider hat sich noch ein anderes Problem eingeschlichen; Verwende ich das Bash-Script, erhalte ich beim Kompilieren folgenden fehler:

\*.h:22:27: calling fdopen: Bad file descriptor
gmake[1]: \*\*\* [\*.o] Error 1
gmake[1]: Leaving directory `/dir\_a/dir\_b/dir\_c/dir\_d'
make: \*\*\* [all] Error 2

Komisscherweise betriff dieser Fehler nicht die mit dem Bash-Script editierten Datein. Die betroffene Datei muss dann jewils gelöscht und neu erstellt werden, damit es wieder funktioniert.

An was kann das liegen?

Gruss
Olli