Datei parsen mit SED

Hallo,

ich arbeite gerade an einem Skript um folgendes zu erreichen.
Ich komme aber nicht mehr voran. Für ein paar Tipps wär ich sehr dankbar.
Ich habe eine Datei die folgendermaßen aufgebaut ist.

…action=M>/xxx/…/…/tag/0000/…/…
…action=M>/xxx/…/…/file/333/…/…
…action=M>/xxx/…/…/directory/555555/…/…

Das geht dann immer so weiter, der aufbau ist immer der gleiche.
Es kommt aber in jeder Zeile „tag“,„file“, oder „directory vor.
Ich möchte jetzt alles in jeder Zeile von „/tag“ ,“/file" oder"/directory" bis zum 2. „/“
herauskopieren und in einer anderen Datei dann einfügen.
Also für die erste Zeile würde ich gern /tag/0000 in die andere Datei kopieren.
Für die 2. Zeile dann /file/333/ usw.
Ich hoffe ihr versteht mein Problem.

Ich hab das versucht mit sed zu lösen. Nur krieg ich es leider nicht hin das ich
einzelne Wörter aus einer einzelnen Zeile herauskopieren kann.

Vielen Dank für ein paar Tipps.

gruß

raffa

Puh, mit SED hab ich Ewigkeiten nicht mehr gearbeitet.

Ich würde es mit substitute (s. z.B.
http://docstore.mik.ua/orelly/unix/sedawk/ch05_03.htm)
probieren; da kannst du mit regulären Ausdrücken die
jeweils nicht benötigten Teile löschen. Achte darauf, dass
Du nicht „/“ als Delimiter benutzt!

Viel Erfolg!

Hallo,
für diese Aufgabe ist der „sed“ nicht ganz glücklich.

Besser geht es mit dem awk:
cat |awk -F/ ’
{ for (i=1;i Field Separator = „/“

Damit werden alle Eingabezeilen mit „/“ getrennte Segmente in Wörter gesplittet und die Wörter x und x+1 auf stdout ausgegeben.

Gruß
Bruno

Vielen Dank für die Hilfe.
Hat super geklappt.
Dank!
Gruß

Hallo raffa,

Du verwendest ein Grundkonstrukt in der Art von
> cat in.txt | sed „{Befehl}“
Der hier geeignete {Befehl} ist „Suche-und-ersetze“ und wird von sed (und „regular expressions“ allgemein) mit dem Buchstaben „s“ abgekürzt.
> s/alt/neu/
ersetzt jedes (erste) „alt“ durch „neu“ in der Zeile.
Da Du den Slash „/“ in Deinem Suchtext hast, ist es hilfreicher, ein andere Zeichen zu verwenden; ich nehme dann oft den Unterstrich „_“:
> s_alt_neu_
tut genau das gleiche, ich aber viel bequemer, wenn man etwa
> s_km/h_Stundenkilometer_
ersetzen möchte.

Was Du noch brauchst ist die Möglichkeit, vorherige Suchergebnisse im „Ersetzen“-Teil wiederzuverwenden. Hierzu ist das „\1“ nützlich:
> s_Ich gehe nach (Berlin)_Otto ging nach \1_

Mit mehreren Orten wäre das natürlich sinnvoller, womit Du dann gleich eine Auswahl ("|") deiner „tag“, „file“ und „directory“ Struktur hast:
> s_…(tag|file|directory)…_…\1…_

Du möchtest nun alles VOR dem „tag“ und so weiter abtrennen; also suchst Du nach allen Zeilen (".*") von Zeilen-Anfang ("^") bis zu einem „/“ hinter dem dann „tag“, „file“ oder „directory“ steht:
> s_^.*/(tag|file|directory)_/\1_

Hinter den drei Schlüsselworten kommt noch ein Slash und dann (nur) Ziffern als zweites Suchfeld:
> s_^.*/(tag|file|directory)/([0-9]*)_/\1/\2_

Um den Rest der Zeile wieder verschwinden zu lassen nimmst Du das abschließende „/“ und jedes weitere Zeichen:
> s_^.*(tag|file|directory)/([0-9]*)/.*_/\1/\2/_

Im „Ersetzen“-Block stehen nur noch die beiden Suchergebnisse \1 und \2 sowie die trennenden „/“
Im Prinzip solltest Du von Zeilen-Anfang ("^") bsi Zeilenende ("$") suchen, aber meine Tests mit
> s_^.*(tag|file|directory)/([0-9]*)/.*$_/\1/\2/_
waren erfolglos.

Zuletzt gilt es noch eine Besonderheit zu beachten: Deine Shell (bash, csh, …) kann eventuell einige Zeien des SED-Befehls vorab (falsch) interpretieren, daher müssen sie mit einem vorangestellten „“ geschützt („escaped“) werden. Dies gilt bei mir (bash) für die Klammern und das Pipe:
> cat in.txt | sed „s_^.*(tag|file|directory)/([0-9]*)/.*_/\1/\2/_“

Viel Erfolg,
Martin

Hi,
das sed script is sicher schon fertig?, oder

ich hab mein spam nicht duchsucht, deshalb nicht geantwortet.

MfG