awk oder sed Zeile ersetzen?

  • Ersteller pfannkuchen2001
  • Erstellt am
pfannkuchen2001

pfannkuchen2001

Aktives Mitglied
Thread Starter
Dabei seit
17.02.2006
Beiträge
2.600
Reaktionspunkte
48
Hi,

ich habe hier eine Datei in der ich eine eine einzige Zeile ersetzen möchte:

die Zeile sieht so aus:
<Setting Name="optiongrfxres">1024 x 768</Setting>


und sie soll so werden:

<Setting Name="optiongrfxres">1920 x 1050</Setting>

Das Problem ist:

es ist nicht immer 1024x768...

ich dachte da an soetwas:
sed -e 's/<Setting Name="optiongrfxres">/./</Setting>"/"<Setting Name="optiongrfxres">1920 x 1050</Setting>/g'
leider funktioniert das aus irgendeinem Grund nicht...

(Am besten wäre es noch, die Aktuelle Bildschirmauflösung abzugreifen... Aber das muss nicht sein)

Gruß

pfannkuchen
 
Den Slash vor Setting würde ich escapen ... :)

s/<Setting Name="optiongrfxres">1024 x 768<\/Setting>/<Setting Name="optiongrfxres">1024 x 1050<\/Setting>
 
äh bitte was?
;)

Was heisst escapen?

EDIT:

Oh lesen muss man auch den ganzen beitrag... Danke ;)
 
Funktioniert aber immernoch nicht wirklich:

sed -e s/<Setting Name="optiongrfxres">1024 x 768<\/Setting>/<Setting Name="optiongrfxres">1024 x 1050<\/Setting> NewProfile.xml
-bash: Setting: No such file or directory


Was auch gehen würde: Immer die 32. Zeile ersetzten! Es ist nämlich immer die gleiche.
also müsste es so aussehen: sed -e 32c"test" NewProfile.xml
leider bekomme ich auch da eine Fehlermeldung:
sed -e 32c"test" NewProfile.xmlsed: 1: "32ctest
": command c expects \ followed by text
 
Zuletzt bearbeitet:
sed 's/<Setting Name="optiongrfxres">1024 x 768<\/Setting>/<Setting Name="optiongrfxres">1024 x 1050<\/Setting>/' blubb.xml > blubb.neu

funktioniert bei mir ... hier auf Arbeit unter Red Hat 5.6
 
Ha!

hier auch... ;)
danke!

Was kann ich nun machen, damit ich nicht nach dem string: <Setting Name="optiongrfxres">1024 x 768<\/Setting>
suche, sondern dass der teil mit der auflösung (1024 x 768) variabel ist - also wen da stehen würde 1233 x 1234 dass es auch funktioniert!?

Das problem wäre: es können 3 und 4 stellige Zahlen sein!

Wäre es da nicht einfacher, die gesamte zeile 32 zu ersetzen?


Gruß

Pfannkuchen
 
Du könntest das Suchmuster variabler gestalten:
Code:
[0-9]+ x [0-9]+
also ungefähr so:
Code:
sed 's/<Setting Name="optiongrfxres">[0-9]+ x [0-9]+<\/Setting>/<Setting Name="optiongrfxres">1024 x 1050<\/Setting>/' blubb.xml > blubb.neu
Habs aber jetzt nicht ausprobiert...
 
Oder gleich mit .* arbeiten:

sed 's/<Setting Name="optiongrfxres">1024 x .*<\/Setting>/<Setting Name="optiongrfxres">1024 x 1050<\/Setting>/' blubb.xml > blubb.n
 
Hallo,

das mit dem "[0-9]+ x [0-9]+" funktioniert so:
sed 's/<Setting Name="optiongrfxres">[0-9]+ x [0-9]+<\/Setting>/<Setting Name="optiongrfxres">1280 x 800<\/Setting>/' ~/Documents/Age\ of\ Empires\ III/Users/NewProfile.xml > ~/Documents/Age\ of\ Empires\ III/Users/NewProfile.xml_new
Nicht.

Eine andere Frage habe ich noch: Wenn ich als eingabe&ausgabe die gleiche Datei nehme, ist sie leer. Warum?
Das ist ja nicht schlimm - dann mache ich eben danach ein mv bla blubb... aber warum ist das so?

Gruß

Pfannkuchen
 
SUuuuper!

Danke!

das hat es gebracht: sed 's/<Setting Name="optiongrfxres">.* x .*<\/Setting>/<Setting Name="optiongrfxres">1280 x 800<\/Setting>/' ~/Documents/Age\ of\ Empires\ III/Users/NewProfile.xml > ~/Documents/Age\ of\ Empires\ III/Users/NewProfile.xml_new

Nun noch eine etwas andere Frage:
was kann ich unter OSX machen, damit sich ein Terminalfenster (bash) schliesst, wenn es die arbeit getan hat?


Gruß

Pfannkuchen
 
Das sed Kommando kann man wesentlich knapper (und damit effizienter) gestalten.
Wenn noch Interesse besteht, schau ich mir das heute Abend mal etwas genauer an.
Im Augenblick habe ich dafür keine Zeit.

Gruß
maceis
 
klar ... war ja auch nur zwischen Tür und Angel!

Alles steht und fällt mit nem gescheiten "Suchkriterium"!
 
Ich wollte das immer schon mal gesagt haben: man kann hier im Unterforum immer wieder neue Schätzchen entdecken... deshalb:

@maceis: Interesse :)
 
Jep, interesse besteht auf jeden fall ;)

Danke schonmal!
 
Ich hab mal folgendes gemacht:

Ersetze in Zeile 32 den Ausdruck
'3 oder vier Ziffern'+'Leerzeichen'+x+'Leerzeichen'+'3 oder vier Ziffern'
durch
'1920 x 1050'

Code:
sed -Ee '32s/[[:digit:]]{3,4} x [[:digit:]]{3,4}/1920 x 1050/'

Außerdem funktioniert:
Code:
sed -e '32s/[[:digit:]]\{3,4\} x [[:digit:]]\{3,4\}/1920 x 1050/'

Meist geht auch:
Code:
sed -Ee '32s/[0-9]{3,4} x [0-9]{3,4}/1920 x 1050/'
das ist aber nicht ganz so portabel.

Alle drei machen das gleiche.
Das zweite Beispiel ist kompatibel mit den veralteten sog. "basic regular expressions".
sed benutzt diese standardmäßig, wenn nicht der Schalter -E angegeben wird.

Gruß
maceis
 
  • Gefällt mir
Reaktionen: gauloisesbert, ruerueka, magheinz und eine weitere Person
Was heisst nun in deinem Beispiel "effizienter"?
Ok, es ist rein von den zeichen kürzer. Aber wesentlich weniger verständlich für mich als vollpfosten ;)

Einen großen geschwindigkeitsunterschied wird es doch nicht geben oder?

Danke aber für den mal wieder sehr qualifizierten Beitrag!

Gruß

Pfannkuchen
 
Effizienter ist das aus verschiedenen Gründen:

  1. Reguläre Ausdrücke sind "teuer".
    Hier wird nur der Teil gesucht, der auch verändert werden soll.
    Da Du einen Teil der Zeile unverändert ausgeben möchtest, muss dieser Teil auch nicht "gefunden" und ersetzt werden.
  2. Da Du schon weißt, in welcher Zeile sich der gesuchte Ausdruck befindet, müssen die anderen Zeilen nicht von Anfang bis Ende durchsucht werden, ob sich der gesuchte Ausdruck darin befindet.
  3. Bei so einen Pattern
    /<Setting Name="optiongrfxres">/
    Wird zuerst in jeder Zeile das Vorkommen von '<' gesucht.
    Das wird wohl bei einer ganzen Reihe von Zeilen gefunden werden.
    Danach wird in allen betreffenden Zeilen untersucht, ob das nächste Zeichen ein 'S' Ist und auch da wird es evtl. einige Treffer geben - und so geht's dann weiter.

    Bei meinem Pattern werden Zeilen, in denen keine Ziffer vorkommt, gar nicht weiter untersucht. und wenn das nächste Zeichen nicht wieder eine Ziffer ist, wird ebenfalls abgebrochen.
  4. Der Ausdruck passt genau auf das, was Du finden möchtest.
    mit dem +-Zeichen anstelle dem {3,4} (man nennt das 'bounds' oder manchmal auch 'quantifier') muss immer noch untersucht werden, ob nach der 4. Ziffer eine weitere Ziffer kommt. Wenn man schon weiß, dass es nicht mehr als 4 sind, kann man sich das sparen und sofort nach dem Leerzeichen Ausschau halten, was wiederum einfacher ist, als auf insgesamt 10 mögliche Zeichen zu untersuchen.

In diesem Fall kommt es vielleicht nicht so darauf an, dass der reguläre Ausdruck ganz genau passt, in anderen Fällen möchtest Du vielleicht präziser einschränken, wann genau ersetzt werden soll.

Auch hast Du vermutlich nur eine Datei, die Du bearbeiten möchtest.
Von daher spielt es wirklich keine große Rolle, wie effizient Dein Kommando ist.

Stell Dir vor es sind tausend Dateien mit jeweils 10.000 Zeilen.
Da machen die kleine "32" und das Weglassen der nicht zu bearbeitenden Teile schon einen gewaltigen Unterschied.

Gruß
maceis
 
Zuletzt bearbeitet:
  • Gefällt mir
Reaktionen: andi42, ruerueka und pfannkuchen2001
Danke sehr (wieder dazu gelernt: {} beim sed nutzen!). Aber warum ist die letzte Zeile möglicherweise nicht so portabel ?
Ich hätte gerade gedacht, [0-9] geht bei regulären Ausdrücken immer, im Gegensatz zu so'nem neumodischen Kram ;) wie [:digit:] ?
 
Steht in 'man re_format':
Ranges are very collating-sequence-dependent, and portable programs should avoid relying on them.

Character classes ([:digit:]) sind doch nicht neumodisch ;).
Gibt es doch schon ewig.
 
Ach weisst du - ich entstamme noch einer Zeit deutlich vor den ersten POSIX BRE/ERE Entwürfen - genauer gesagt sogar noch vor POSIX itself ;)

Zu meiner Zeit war alles anders - selbstverständlich viel besser :D
 
Zurück
Oben Unten