Archiv verlassen und diese Seite im Standarddesign anzeigen : Shell Script soll Einträge in Datei ändern
CaptainAlphabet
07-02-2004, 23:17
Wisst ihr, wie ein Shell Script die Zeilen, die es sich mit "grep" aus einer anderen Datei rausgesucht hat, verändern kann?
Direktes Ändern geht nicht, Nur über eine temporäre Datei mit sed.
sed -e s/alt/neu/ datei.alt >datei.neu
mv -f datei.neu datei.alt
CaptainAlphabet
08-02-2004, 11:58
Danke!
Kannst du mir auch sagen, wie ich eine komplette Zeile ersetzen kann, wenn ich nur dessen Anfang kenne?
Beispiel (unterstrichener Text unbekannt):
[...]
CaptainAlphabet kriegt's nicht hin.
[...]
sed s/CaptainAlphabet/CaptainAlphabet hat's geschafft/ Beispiel.alt > Beispiel.neu
würde nämlich ausgeben:
[...]
CaptainAlphabet hat's geschafftkriegt's nicht hin.
[...]
peschmae
08-02-2004, 12:15
Mit
sed s/CaptainAlphabet/CaptainAlphabet hat's geschafft/ Beispiel.alt > Beispiel.neu
sucht sed nur nach CaptainAlphabet und ersetzt dementsprechend auch nur das. Damit die ganze Zeile gefunden und damit nachher auch ersetzt wird machst du sowas:
sed s/CaptainAlphabet.*/CaptainAlphabet hat's geschafft/ Beispiel.alt > Beispiel.neu
(Sed arbeitet per Default Zeilenweise - wenn du einen Ausdruck auf das ganze Dokument, über Zeilengrenzen hinweg anwenden musst, dann ist ein Spezialparameter an Sed fällig)
Falls nur alle CaptainAlphabet-Zeilen mit CA am Anfang gefunden werden sollen geht das dann mit ^
sed s/^CaptainAlphabet.*/CaptainAlphabet hat's geschafft/ Beispiel.alt > Beispiel.neu
In diesem Beispiel musst du aber aufpassen, weil das ' das eingesetzt wird benutzt wird um eine Zeichenkette zwischen zwei ' vor dem ersetzt werden zu schützten - das läuft dann in dem Fall auf sowas hinaus:
sed s/^CaptainAlphabet.*/"CaptainAlphabet hat"\'"s geschafft"/ Beispiel.alt > Beispiel.neu
Die " sind nötig um die Leerschläge zu schützen (könntest auch jeweils ein \ vor jeden Leerschlag pflanzen) - müssen aber vor dem ', das ja ein normales Zeichen ist aufhören - das muss separat mit einem \ Escaped werden...
Noch n bisschen Lektüre: Klick (http://www.student.northpark.edu/pemente/sed/) und Klick (http://www.grymoire.com/Unix/index.html) .
Und zum Trost: So einfache sachen krieg ich zwar meist einfach so hin - aber schon ein bisschen kompliziertere Sachen muss ich auch nachschlagen.
MfG Peschmä
CaptainAlphabet
08-02-2004, 15:15
Danke!
Ich habe auch versucht mir Wildcards zu arbeiten, aber der Punkt vor dem Stern war mir neu.
peschmae
08-02-2004, 17:03
Sed arbeitet halt mit Regexps. Und dort gilt:
*: Das vorherige Zeichen mindestens 0 mal
+: Das vorherige Zeichen mindestens 1 mal
?: Das vorherige Zeichen 0 oder 1 mal
uvam.
.: irgend ein Zeichen
Das wars schon. :)
MfG Peschmä
sticky bit
08-02-2004, 17:56
Wenn es auch PERL sein darf:
perl -p -i -e 's/^.*schaffts nicht$/Andere Zeile/' datei
würde dann alle Zeilen die mit "schaffsts nicht" enden in "Andere Zeile" ändern.
Für alles weitere gibt man perl bzw. perldoc perl und deren weiterführende Dokumente sowie zahlreiche Webseiten Auskunft...
peschmae
08-02-2004, 18:23
Das ist aber Overhead :eek:
Sed ist bei mir 36KB, Perl 1.1MB gross. Geht natürlich genau so gut :)
MfG Peschmä
Hi!
Da ich ein aehnliches Problem habe, waerme ich diesen thread mal wieder auf ;)
c-shell, sed.
In einer Schleife sollen einige Dateien editiert werden; diese sind nacheinander in ${file} zu finden.
Ich habe eine Variable ${prefix}, mit der ich Zeilen der Form:
#include "NSnochwas.inc"
fuer ${prefix}=TS in
#include "TSnochwas.inc"
aendern moechte.
Mittel der Wahl ist sed.
Von allen Versuchen, in denen ich mit " \ # . * um mich geschmissen habe, soll dieser hier als Beispiel dienen:
sed s/\#include \"NS.*/\#include \"${prefix}.*/ ${file} > ${file}.tmp
Ich bekomme nur "sed: No match."
Zum einen weiss ich nicht, wie ich das # da reinbekomme (oder wo sonst noch Fehler sind), zum anderen denke ich nicht, das das zweite .* funktioniert...
Wenn mir jemand von Euch in diesem Problem weiterhelfen koennte, waere das toll
Danke im Voraus
kamome
Nachdem ich nun gesehen habe, dass ich das .* (vermutlich) gar nicht benutzen sollte, habe ich es mal hiermit versucht:
sed s/"#"include" "\"NS/"#"include" "\"${prefix}/ ${file} > ${file}.tmp
Und tatsaechlich - keine Fehler_meldung_ mehr... es passiert (fuer mich erkennbar) aber auch nichts in den Dateien!?
Wer kann mir da weiterhelfen?
tia
kamome
peschmae
06-08-2004, 18:18
Quark. Überkompliziert. So. Jetzt noch ein Versuch von mir:
sed "s/#include \"NS/#include \"${prefix}/" -i test.txt
bearbeitet direkt in test.txt - also ohne aus einer Datei zu lesen und in eine andere Datei zu schreiben (d.h. eigentlich schon aber das merkst du nicht)
Die Variante aus dem zweiten Post geht aber auch. Bei mir. Bist du sicher dass du richtig geguckt hast? Die Änderungen liegen in ${file}.tmp - um die in die Originaldatei zurückzukriegen musst du -i verwenden wie oben oder mit mv ${file}.tmp ${file} die Datei verschieben.
MfG Peschmä
Danke Peschmae,
mit Deiner Erinnerung (.tmp) hast Du ins Schwarze getroffen :)
Die .tmp Dateien wurden tatsaechlich editiert, allerdings steht da jetzt immer "${prefix}" also die Variable nicht aufgeloest.
Leider bekomme ich mit dem von Dir vorgeschlagenen
sed "s/#include \"NS/#include \"${prefix}/" ${file} > ${file}.tmp
sed: -e expression #1, char 15: Unterminated `s' command
(das sed auf dem Rechner kann kein -i)
"Denkt" er vielleicht nur bis zum zweiten " ?
Daher habe ich " durch ' ersetzt:
sed 's/#include \"NS/#include\"${prefix}/" ${file} > ${file}.rmp
Und nun "geht" es wieder - so wie bei meiner zweiten Version: "${prefix}" statt ${prefix}, wieder nicht ersetzt.
Sowohl die " alsauch die ' verhindern wohl das Aufloesen der Variablen durch die shell.
!!!!!
!!!!!Ah, mit dieser Idee bin ich eben auf eine (dreiviertel) Loesung gekommen:
!!!!!
set locprefix=\"${prefix}
sed "s/#include..NS/#include ${locprefix}/" ${file} > ${file}.tmp
Das funktioniert! :D (Wenn es auch das syntaktische Problem umgeht statt es zu loesen)
Falls Du (oder andere) also noch eine "richtige" Loesung haben...
Ich wuerde mich sehr freuen da noch was zu erfahren.
Noch einmal vielen Dank bis hierher.
kamome
peschmae
07-08-2004, 08:43
Ich nutze die Bash - liegt wohl daran das mein Zeugs bei dir nicht ging. Die Variablen-Verhinderung bzw nichtverhinderung dort kenne ich - k.A. wie das bei der C-Shell ist.
Versuch mal das:
sed "s/#include \"NS/#include \""${prefix}/ < test.txt > test.txt.tmp
MfG Peschmä
Powered by vBulletin® Version 4.2.5 Copyright ©2025 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.