ubuntuusers.de

Zeilen Verschieben mit SED

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

tsueri87

Anmeldungsdatum:
10. August 2014

Beiträge: Zähle...

Hallo liebe Forumsleute

ich bin noch relativ unerfahren mit der Shell und bin aber fleissig am Experimentieren und Lösungen für meine Probleme zu finden. Nun stehe ich aber bei einem Problem an, bei dem ihr mir hoffentlich weiterhelfen könnt.

Aufgabe: Ich muss in rund 1000 xml-Dateien jeweils zwei Zeilen verschieben. Alle Dateien sind gleich strukturiert, von daher sollte es also keine Probleme geben. Und zwar geht es darum, dass ich die Zeile 20 auf die Zeile 8 kriege. Die Originaldatei sieht folgendermassen aus:

Originaldatei:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
?xml version="1.0" encoding="UTF-8"?>
<document xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:noNamespaceSchemaLocation="vorlage.dtd">
   <meta>
       <id>200455</id>
       <author></author>
       <url></url>
       <date></date>
[...]
   <text>
       <date>1941-06-01</date>

Ich hab dazu ein sed-Script mit Hilfe vieler Forenbeiträge gebastelt, aber irgendwie funktioniert es nicht:

1
for file in *.xml; do sed -i -f -e '20{h;d}' -e '8g' $file; done

Wenn ich es laufen lasse, dann krieg ich folgende Fehlermeldung:

1
2
sed: 1: "20{h;d}
": extra characters at the end of d command

Kann mir jemand weiterhelfen? Ich hab schon einiges ergoogelt, steh aber voll auf dem Schlauch :s. Danke schon zum Voraus! LG Tsueri

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13175

tsueri87 schrieb:

Hallo liebe Forumsleute

Herzlich willkommen hier im Forum!

Aufgabe: Ich muss in rund 1000 xml-Dateien jeweils zwei Zeilen verschieben. Alle Dateien sind gleich strukturiert, von daher sollte es also keine Probleme geben. Und zwar geht es darum, dass ich die Zeile 20 auf die Zeile 8 kriege.

So etwas macht man besser mit Werkzeugen, die XML verarbeiten können, z.B. xmlstarlet oder Ruby mit dem Gem Nokogiri.

Ich hab dazu ein sed-Script mit Hilfe vieler Forenbeiträge gebastelt, aber irgendwie funktioniert es nicht:

Das wirst Du mit sed auch nicht so ohne weiteres hinbekommen, denn Du willst ja eine Zeile nach vorne verschieben.

1
for file in *.xml; do sed -i -f -e '20{h;d}' -e '8g' $file; done

Die Option "-f" hat dort nichts zu suchen. Du solltest auch die Dateinamen quoten.

Kann mir jemand weiterhelfen? Ich hab schon einiges ergoogelt, steh aber voll auf dem Schlauch :s.

Mit sed brauchst Du einen Ansatz in zwei Schritten:

  1. Extrahieren von Inhalt aus Zeile 20

  2. Einfügen des Extrakts in Zeile 8 und löschen von Zeile 20

Z.B. so:

1
2
3
4
for f in *.xml; do
  date=$(sed -ne '20 s#^.*<date>\([^<]*\)</date>.*$#\1#p' "$f")
  sed -i.bak -e '8 s#^\(.*<date>\)[^<]*\(</date>.*\)$#\1'"$date"'\2#; 20 d' "$f"
done

Aber, wie gesagt, das geht sofort kaputt, wenn die Zeilennummern nicht mehr passen. Besser wäre ein Tool, das XML verarbeitet und XPath-Ausdrücke beherrscht.

Ciao

robert

user_unknown

Avatar von user_unknown

Anmeldungsdatum:
10. August 2005

Beiträge: 17604

Wohnort: Berlin

Ich käme auf eine ähnliche Lösung:

1
dt=$(sed -n '20p' $file); sed -i "8 s|.*|$dt|;20d" $file

Weil Sed zeilenorientiert arbeitet und von vorne nach hinten ist Zeile 8 lange vorbei, bevor man Zeile 20 gelesen hat. Ob man von 8-19 alles puffern kann um es ab Z. 20 zu schreiben, weiß ich nicht - mit den Pufferbefehlen bin ich nie recht warm geworden.

Hier liest man einfach Zeile 20 in eine Variable, und ersetzt dann alles in Zeile 8 mit der Variablen, löscht dann Zeile 20.

track

Avatar von track

Anmeldungsdatum:
26. Juni 2008

Beiträge: 7174

Wohnort: Wolfen (S-A)

Hi tsueri87,

zuerst mal willkommen hier auf dem Forum !

Ich würde auch sagen: wenn das gültiges XML ist, hat da sed und (zeilenorientierte) Konsorten nix dran verloren.
Nimm xmlstarlet ed -m und alles ist gut. Ok, man muss sich da erst etwas mit der Syntax anfreunden, aber dann ist es solide.

Kannst Du denn mal eine komplette XML- Beispieldatei posten ? - dann könnte ich gucken, ob ich einen Vorschlag hinkriege ...

LG,

track

Lysander

Avatar von Lysander

Anmeldungsdatum:
30. Juli 2008

Beiträge: 2669

Wohnort: Hamburg

Alternativ könnte man das auch mit XSLT lösen - aber das ist auch nicht wirklich handlich 😬

@tsueri87 Du willst in Wirklichkeit keine Zeilen verschieben, sondern Knotenelemente einer XML-Struktur! Ja, das XML liegt Dir hier als Datei vor, aber es gibt keine Garantie über die Formatierung. Eine genauso gültige Repräsentation könnte auch in *einer* Textzeile stehen, ohne Umbrüche und Einrückungen... daher sind Text orientierte Werkzeuge bei XML selten eine gute Idee...

user_unknown

Avatar von user_unknown

Anmeldungsdatum:
10. August 2005

Beiträge: 17604

Wohnort: Berlin

Lysander schrieb:

Alternativ könnte man das auch mit XSLT lösen - aber das ist auch nicht wirklich handlich 😬

@tsueri87 Du willst in Wirklichkeit keine Zeilen verschieben, sondern Knotenelemente einer XML-Struktur!

Falsch. Beides sind unterschiedliche Beschreibungen des gleichen Sachverhalts. Wenn die Daten von einem Programm generiert werden gibt es keinen Grund anzunehmen, dass sich die Struktur künftig ändern wird, und wenn sie sich ändern wird ist keineswegs gesagt, dass das XML stabil bleibt.

Ja, das XML liegt Dir hier als Datei vor, aber es gibt keine Garantie über die Formatierung.

Gibt es bei XML auch nicht.

Eine genauso gültige Repräsentation könnte auch in *einer* Textzeile stehen, ohne Umbrüche und Einrückungen... daher sind Text orientierte Werkzeuge bei XML selten eine gute Idee...

Falsch. Eine solche Umformung ist theoretisch denkbar aber praktisch unwahrscheinlich. Ob eine pragmatische Lösung hier nicht das beste ist lässt sich gar nicht sagen.

Lysander

Avatar von Lysander

Anmeldungsdatum:
30. Juli 2008

Beiträge: 2669

Wohnort: Hamburg

user unknown schrieb:

Falsch. Beides sind unterschiedliche Beschreibungen des gleichen Sachverhalts.

Falsch. Meine Aussage beschreibt das Problem auf Domänenebene und ist damit unabhängig von der physischen Repräsentation. Die Aussage des OP ist hingegen wesentlich allgemeiner und Domänen unabhängig. Der Sachverhalt ist also nicht gleich.

Wenn die Daten von einem Programm generiert werden gibt es keinen Grund anzunehmen, dass sich die Struktur künftig ändern wird,

Ach ist dem so? XML wird idR. nicht "von Hand zusammen geklöppelt", sondern durch Standard-Libs. In diesen können sich sehr wohl Änderungen bei der Serialisierung ergeben. Ein Programm kann diese auch wechseln usw. Im Softwarebereich gibt es eigentlich immer nur eine Konstante: Änderungen! 😉

und wenn sie sich ändern wird ist keineswegs gesagt, dass das XML stabil bleibt.

Das stimmt - aber dann muss höchst wahrscheinlich auch am Zeilen orientierten Script etwas ändern 😉

Ja, das XML liegt Dir hier als Datei vor, aber es gibt keine Garantie über die Formatierung.

Gibt es bei XML auch nicht.

Ja eben!

Falsch. Eine solche Umformung ist theoretisch denkbar aber praktisch unwahrscheinlich.

Falsch! In der Praxis kommt das öfter vor, als man denkt. Bei Webservices via XML ist z.B. nie gesagt, wie das beim Server ankommt. Ist ja auch uninteressant, sofern es valide ist!

Ob eine pragmatische Lösung hier nicht das beste ist lässt sich gar nicht sagen.

Habe ich auch nicht. Aber eine gute Idee ist das eben *selten*! (Vor allem, wenn man nicht weiß, dass sich XML in der Repräsentation unterscheiden kann!)

user_unknown

Avatar von user_unknown

Anmeldungsdatum:
10. August 2005

Beiträge: 17604

Wohnort: Berlin

Aufgabe: Ich muss in rund 1000 xml-Dateien jeweils zwei Zeilen verschieben. Alle Dateien sind gleich strukturiert, von daher sollte es also keine Probleme geben.

Bisher war überhaupt nicht die Rede davon, dass es in Zukunft wieder solche Dateien geben wird, die wieder bearbeitet werden müssen. Das ganze Szenario die Zukunft betreffend ist pure Einbildung.

Antworten |