ubuntuusers.de

Source Files per Skript anpassen

Status: Gelöst | Ubuntu-Version: Kein Ubuntu
Antworten |

thomsen

Avatar von thomsen

Anmeldungsdatum:
9. Juni 2010

Beiträge: 188

Wohnort: Hamburg

Hallo zusammen,

ich versuche eine API unter AIX zu kompilieren und muss aus verschiedenen Gründen hierfür den xlC Compiler verwenden (gcc funzt nicht, hab ich schon probiert). Jedoch haben die Header-Dateien in besagter API immer "#pragma once" für den Precompiler, damit es nur einmal angezogen wird. Jedoch kennt xlC diesen Befehl leider nicht.

Was ich also möchte ich per kurzem ksh-konformen Shell-Skript allen .h Files in meiner Ordnerstruktur, die ein "#pragma once" beinhalten folgendes voranstellen:

1
2
#ifndef <Eindeutiger Identifier>
#def <Eindeutiger Identifier>

sowie folgendes hintenran packen

1
#endif

Der Identifier ist am einfachsten wohl der Dateinamen vor dem .h in Capital-Lettern. Bessere Ideen sind natürlich willkommen.

Lysander

Avatar von Lysander

Anmeldungsdatum:
30. Juli 2008

Beiträge: 2669

Wohnort: Hamburg

Vorschlag:

  • Geh die Dateien per Schleife durch

  • prüfe mit grep, ob das Muster vorkommt

  • Wenn ja, ergänze die Datei mittels sed um die gewünschten Zeilen

user_unknown

Avatar von user_unknown

Anmeldungsdatum:
10. August 2005

Beiträge: 17624

Wohnort: Berlin

Mit einer Datei tfs.sh:

1
2
3
4
5
6
7
#!/bin/bash
#
f=$1
sed -i '1a#ifndef @id@\n#def @id@' $f
sed -i '$a#endif' $f
F=${f^^}
sed -i "s @id@ $F " $f
1
find -name "*.c" -execdir tfs.sh {} ";"

thomsen

(Themenstarter)
Avatar von thomsen

Anmeldungsdatum:
9. Juni 2010

Beiträge: 188

Wohnort: Hamburg

user unknown schrieb:

Mit einer Datei tfs.sh:

1
2
3
4
5
6
7
#!/bin/bash
#
f=$1
sed -i '1a#ifndef @id@\n#def @id@' $f
sed -i '$a#endif' $f
F=${f^^}
sed -i "s @id@ $F " $f
1
find -name "*.c" -execdir tfs.sh {} ";"

Danke dir user unknown für die schnelle Antwort. Ich habe es auf Basis dessen, was du mir hier vorgegeben hast wie folgt durchgeführt:

Datei pragma.ksh erstellt:

1
2
3
4
5
6
7
#!/bin/ksh
#
f=$1
sed -i '1a#ifndef @id@\n#def @id@' $f
sed -i '$a#endif' $f
F=${f^^}
sed -i "s @id@ $F " $f

Dann find ausgeführt:

1
find ./ -name "*.h" -exec pragma.ksh {} ";"

"-execdir" kennt er als Parameter für find nicht. Und ich möchte doch auch nur dieses Skript ausführen. Daher habe ich es mit "-exec" ausgetauscht. Leider ist das Resultat auch nur eine Reihe von Fehlermeldungen. Für jedes File, dass er mit find findet und für dieses das Shell-Skript ausführt gibt er folgende Meldungen aus:

1
2
3
4
5
6
7
sed: illegal option -- i
Usage:  sed [-n] Script [File ...]
        sed [-n] [-e Script] ... [-f Script_file] ... [File ...]
sed: illegal option -- i
Usage:  sed [-n] Script [File ...]
        sed [-n] [-e Script] ... [-f Script_file] ... [File ...]
./pragma.ksh[6]: F=${f^^}: bad substitution

thomsen

(Themenstarter)
Avatar von thomsen

Anmeldungsdatum:
9. Juni 2010

Beiträge: 188

Wohnort: Hamburg

Okay, hab mir gerade mal die man-pages auf der AIX-Maschine und meiner Ubuntu-Maschine verglichen und musste feststellen, dass auf der AIX-maschine kein GNU-sed ist und das sed dort den -i Parameter nicht kennt.

Also wie gesagt, ich brauche das ganze für die Korn-Shell und nicht für die Bourne-again Shell und das ganze unter AIX 6.1.

Vain

Avatar von Vain

Anmeldungsdatum:
12. April 2008

Beiträge: 2510

Servus,

dann musst du ganz altmodisch Zwischendateien nehmen. sed -i macht, soweit ich weiß, übrigens auch nichts anderes.

1
2
3
sed "...pattern1..." "$f" > "$f.step1"
sed "...pattern2..." "$f.step1" > "$f.step2"
# usw

Das ${foo^^} als Funktion, um alle Kleinbuchstaben durch große zu ersetzen, gibt es auch in der Bash erst seit Version 4. Eine Steinzeit-ksh kann das natürlich nicht. 😐 Vielleicht kommst du hier mit tr weiter:

$ echo hallo Welt | tr 'a-z' 'A-Z'
HALLO WELT

thomsen

(Themenstarter)
Avatar von thomsen

Anmeldungsdatum:
9. Juni 2010

Beiträge: 188

Wohnort: Hamburg

Vain schrieb:

Servus,

dann musst du ganz altmodisch Zwischendateien nehmen. sed -i macht, soweit ich weiß, übrigens auch nichts anderes.

1
2
3
sed "...pattern1..." "$f" > "$f.step1"
sed "...pattern2..." "$f.step1" > "$f.step2"
# usw

Das ${foo^^} als Funktion, um alle Kleinbuchstaben durch große zu ersetzen, gibt es auch in der Bash erst seit Version 4. Eine Steinzeit-ksh kann das natürlich nicht. 😐 Vielleicht kommst du hier mit tr weiter:

$ echo hallo Welt | tr 'a-z' 'A-Z'
HALLO WELT

Hallo Vain, Besagtes habe ich auch parallel durchgeführt. Ersteres habe ich genauso gelöst, bei zweiterem habe ich mit sed noch einige Zwischenschritte durchgeführt, um die Sonderzeichen zu entfernen und so einen eindeutigen String zu erhalten.

Meine "pragma.ksh" sieht nun wie folgt aus:

1
2
3
4
5
6
7
#!/bin/ksh
#
sed '1a#ifndef @id@\n#def @id@' $1 > $1.new && mv $1.new $1
sed '$a#endif' $1 > $1.new && mv $1.new $1
idtag = $(echo $1 | sed 's/[\.\/]//g' | tr 'a-z' 'A-Z')
echo $idtag
sed "s @id@ $idtag " $1 > $1.new && mv $1.new $1

Damit löse ich zumindest die vorherigen Fehler... um in die nächsten reinzulaufen:

1
2
3
sed: Function 1a#ifndef @id@\n#def @id@ cannot be parsed.
sed: Function $a#endif cannot be parsed.
./pragma.ksh[7]: idtag:  not found

Gut, er hat irgendein Problem mit der Syntax zum Einfügen der neuen Zeilen. Ich weiß nicht warum, aber das verstehe ich noch. Aber was ich sehr merkwürdig finde ist, dass er meiner Variable "idtag" den Wert nicht zuweisen will.

thomsen

(Themenstarter)
Avatar von thomsen

Anmeldungsdatum:
9. Juni 2010

Beiträge: 188

Wohnort: Hamburg

Gut, da ich keinen anderen Weg gefunden habe, hab ich nun sowohl bash als auch GNU-sed auf dem AIX installiert. Die Parsingfehler verschwinden hiermit, jedoch nicht letztere Fehlermeldung:

1
./pragma.sh[7]: idtag:  not found

Vain

Avatar von Vain

Anmeldungsdatum:
12. April 2008

Beiträge: 2510

GNU to the rescue, hm? ☺

thomsen schrieb:

1
2
3
4
#!/bin/ksh
...
idtag=$(echo $1 | sed 's/[\.\/]//g' | tr 'a-z' 'A-Z')
...

Vor und nach dem Gleichheitszeichen keine Leerzeichen. Da ist die Shell pingelig.

Das mit dem Einfügen bei sed war übrigens auch eine GNU-Eigenheit. „Normalerweise“ (zum Beispiel mit dem sed von FreeBSD) sieht der a-Befehl so aus:

sed '$a \
Text zum einfügen in der letzten Zeile \
kann auch mehrere Zeilen lang sein \
alle bis auf die letzte müssen mit Backslash enden
' datei

(Auch dann, wenn man nur eine Zeile einfügen will. Ja, ist lästig, deswegen kann GNU sed mehr.)

thomsen

(Themenstarter)
Avatar von thomsen

Anmeldungsdatum:
9. Juni 2010

Beiträge: 188

Wohnort: Hamburg

Japp, an den Leerzeichen lag es...

Das Skript funktioniert nun. Die gesamte Komilierung zwar noch nicht, da der Linker nicht das will, was ich will, aber das ist eine andere Geschichte.

Danke nochmals.

Antworten |