Linux - sed

Seite 1 von 1 - Forum: Coding Stuff auf overclockers.at

URL: https://www.overclockers.at/coding-stuff/linux_sed_212864/page_1 - zur Vollversion wechseln!


Zorr schrieb am 22.12.2009 um 12:38

ich bin gerade dabei ein shell-script zu schreiben wo ich unter anderem auch das start-script von apache modifizieren will. bis jetzt habe ich eigentlich immer nur eine zeile ändern wollen, nun sinds aber mehrere. bzw möcht ich ein paar zeilen an einer bestimmten stelle einfügen. das problem ist nun dass ich eben nicht weiß wie ich eine weitere zeile darstelle und dass am anfang der zeilen auch tabs sind und ich nicht weiß wie ich diese bei der suche bzw beim einfügen darstellen soll.

was zurzeit funktioniert ist:

Code:
sed -e 's/\tstart)/ersetzt/' /etc/init.d/apache2

da erkennt er den tab (\t) aber wie ich nach mehreren zeilen suche weiß ich nicht.

gegooglet hab ichs auch schon, nur finde ich da nichts, bzw funktionieren die vorschläge nicht.

wär super wenn mir da vll jemand ein bsp posten kann, wo ein text über mehrere zeilen mit tabs ersetzt wird. oder noch besser: wo an diesem gesuchten text wieder mehrere zeilen mit tabs drangehängt werden!

ich hoffe dass das ich das irgwie verständliche rübergebracht hab und mir da jemand helfen kann! :confused:
(im konkreten gehts um die anleitung http://www.luebben-home.de/blog/InstallationModsecurity)

tia!


Lukas schrieb am 22.12.2009 um 12:43

Möchtest du den Text den es zu ersetzen gilt global (über das ganze Dokument hinweg) ersetzen?

Wenn ja dann häng beim subsitute noch /g dran. Also:

Code:
sed -e 's/\tstart)/ersetzt/g' /etc/init.d/apache2


davebastard schrieb am 22.12.2009 um 13:06

sowie ich es verstanden habe will er einen text über mehrere Zeilen an einer bstimmten stelle einfügen

Code:
sed -e '10/TextTextText\nTextTextText/p' /etc/init.d/apache2

10 wär die zeilennummer, das p am schluss für print. ob "\n" einen zeilenumbruch produziert ist eher eine Vermutung aber das würd sich sicher leicht rausfinden lassen...

http://www.tty1.net/sed-tutorium/se...e-schritte.html


Zorr schrieb am 22.12.2009 um 13:14

@lukas: das mit dem g am schluss ist mir schon klar. der text den ich suche, kommt aber eh nur einmal im dokument vor.

@dave: ja genau ich möchte einen text einfügen, aber ohne dabei eine konkrete zeilennr anzugeben, da sich die ja möglicherweise ändern kann. also soll das ganze dynamisch sein und zuerst den text suchen, wo ich dann meinen text dranhäng.

das

Code:
sed -e 's/\tstart)/ersetzt/' /etc/init.d/apache2
ist nur ein bsp gewesen.
nach dem "\tstart)" kommen noch ein paar zeilen. genauer gesagt das hier:
Code:
                log_daemon_msg "Starting web server" "apache2"
                if $APACHE2CTL start; then
                        if check_htcacheclean ; then
                                log_progress_msg htcacheclean
                                start_htcacheclean || log_end_msg 1
                        fi
aber da weiß ich eben nicht wie ich das in die suche miteinbeziehe...


watchout schrieb am 22.12.2009 um 15:40

die zeilen per \n zu trennen geht nicht? Sollte eigentlich schon


COLOSSUS schrieb am 22.12.2009 um 15:45

Abgesehen davon, dass ich es fuer keine gute Idee halte, das Apache-Initscript zu verstuemmeln: Wieso nicht einfach ueber die Zeilennummer arbeiten?

Poste bitte sowohl die (vollstaendige) Datei, wie sie jetzt aussieht, und das Ergebnis, das du gerne generieren wuerdest. Dann finden wir sicher eine Loesung.

Uebrigens sollte der Thread "GNU - sed" heiszen :D


that schrieb am 22.12.2009 um 15:45

Also wenn ich nach "sed insert line" suche, kommt folgendes als erstes Ergebnis:

http://www.grymoire.com/Unix/Sed.html


Zorr schrieb am 22.12.2009 um 16:18

ok also im moment sieht der abschnitt im apache-skript so aus:

Code:
        start)
                log_daemon_msg "Starting web server" "apache2"
                if $APACHE2CTL start; then
                        if check_htcacheclean ; then
                                log_progress_msg htcacheclean
                                start_htcacheclean || log_end_msg 1
                        fi
                        log_end_msg 0
                else
                        log_end_msg 1
                fi
        ;;
(vor dem "start)" ist allerdings noch ein tab, welchen er hier aber anscheinend wegschneidet)

und so möchte ich es haben:

Code:
        start)
                log_daemon_msg "Starting web server" "apache2"
                if $APACHE2CTL start; then
                        if check_htcacheclean ; then
                                log_progress_msg htcacheclean
                                start_htcacheclean || log_end_msg 1
                        fi
                        if [ ! -L /var/run/apache2.pid ]; then
                                ln -s /chroot/var/run/apache2.pid /var/run/apache2.pid
                        fi
                        log_end_msg 0
                else
                        log_end_msg 1
                fi
        ;;

wenn ich jetzt mal probehalber folgendes versuche:
Code:
sed -e 's/\tstart)\n\t\tlog_daemon_msg/dreck/' /etc/init.d/apache2
also die erste Zeile und einen teil der 2ten zeile durch "dreck" auszutauschen, macht er gar nix. also findet es anscheinend nicht.

jedoch
Code:
sed -e 's/\tstart)/\tdreck/' /etc/init.d/apache2
funktioniert und "<tab>start)" wird mit "<tab>dreck" ausgetauscht

also gehts jetzt hauptsächlich darum wie ich dieses "nächste zeile" einbaue. mit \n klappts ja anscheinend nicht oder ich mach irgwas falsch :confused:
bin grad draufkommen, dass \n beim einfügen funktioniert. also wenn ich schreib
Code:
sed -e 's/\tstart)/\a\n\n\ndreck/' /etc/init.d/apache2
dann ersetzt er mir halt "start)", schreibt 3 leere zeilen und dann "dreck"


watchout schrieb am 22.12.2009 um 16:47

Ich hab grad nachgelesen und sed is line-based, also ist es etwas scheinbar komplizierter, in thats Link ist übrigens ein Kapitel darüber: http://www.grymoire.com/Unix/Sed.html#uh-47


Ich selbst würd's in dem Fall komplett anders angehen
* da ja start) unique ist (sein sollte)
* und wenn sich der Code zwischen start) und der Zeile die du einfügen willst ändert sowieso dein Pattern nicht mehr funktioniert
(wichtig)

Nimm die Zeilen die dazwischen stehen, mach ein md5, sha wwi Hash daraus, und aufschreiben.

In deinem Script selectest du genau die Zeilen per sed, awk, oder was du halt magst, generierst den Hash und vergleichst den. Wenn er übereinstimmt fügst du die Zeilen an start) + K ein (K muss konstant sein wenn der Hash stimmt)
Als nettes Nebenprodukt kannst du vor sed/awk schon einen Fehler ausgeben wenns nicht funktioniert.


that schrieb am 22.12.2009 um 17:20

Zitat von watchout
Ich hab grad nachgelesen und sed is line-based, also ist es etwas scheinbar komplizierter, in thats Link ist übrigens ein Kapitel darüber: http://www.grymoire.com/Unix/Sed.html#uh-47

Das passende Kapitel ist wohl dieses:

http://www.grymoire.com/Unix/Sed.html#uh-40

Und kompliziert ist das überhaupt nicht:

sed -e '/Suchbegriff/aDas hier kommt in eine neue Zeile nach dem Suchbegriff'


watchout schrieb am 22.12.2009 um 17:26

Zitat von that
Das passende Kapitel ist wohl dieses:

http://www.grymoire.com/Unix/Sed.html#uh-40

Und kompliziert ist das überhaupt nicht:

sed -e '/Suchbegriff/aDas hier kommt in eine neue Zeile nach dem Suchbegriff'
Ich meine aber multi-line patterns wären kompliziert (dahin führt auch der Link) also Patterns welche über ein \n hinausgehen


Zorr schrieb am 22.12.2009 um 17:37

hmm danke auf jeden fall mal für die antworten!

das mitm hash klingt mir ein bissl zu kompliziert. vll mach ich das dann doch mit der zeilennr ^^ bzw nicht einfach nur die zeilennr angeben, sondern zeilennr von start + 7 oder so
also

Code:
sed -n '/\tstart)/ =' /etc/init.d/apache2
+ 7

pfusch oder genehmigt? :D


watchout schrieb am 22.12.2009 um 17:45

Zitat von Zorr
hmm danke auf jeden fall mal für die antworten!

das mitm hash klingt mir ein bissl zu kompliziert. vll mach ich das dann doch mit der zeilennr ^^ bzw nicht einfach nur die zeilennr angeben, sondern zeilennr von start + 7 oder so
also
Code:
sed -n '/\tstart)/ =' /etc/init.d/apache2
+ 7

pfusch oder genehmigt? :D
Da du nicht sagst wozu du es brauchst: pfusch ;)

Und... Wieso kompliziert :confused:

Das mit dem Hash wär eben genau die Lösung, nur dass du mit dem Hash sicherstellst dass das was du tatsächlich überspringst auch das gleiche ist was du überspringen willst.


Zorr schrieb am 22.12.2009 um 18:24

ok aber dadurch dass "\tstart)" sowieso nur einmal vorkommen darf, müsste ein hashvergleich ja gar nicht notwendig sein oder?

Zitat von watchout
Da du nicht sagst wozu du es brauchst: pfusch ;)

ich bin dabei ein skript zu schreiben, das automatisch einen webserver aufsetzt und grundlegende sicherheiteinstellungen vornimmt (chroot, modsecurity etc)


watchout schrieb am 23.12.2009 um 12:55

Zitat von Zorr
ok aber dadurch dass "\tstart)" sowieso nur einmal vorkommen darf, müsste ein hashvergleich ja gar nicht notwendig sein oder?



ich bin dabei ein skript zu schreiben, das automatisch einen webserver aufsetzt und grundlegende sicherheiteinstellungen vornimmt (chroot, modsecurity etc)
Du sollst ja nicht das start) hashen sondern das was zwischen start) und zeile +7 liegt




overclockers.at v4.thecommunity
© all rights reserved by overclockers.at 2000-2025