ganze Absätze ersetzen

U

ulukai

Jungspund
Hallo Leute
Ich bin gerade dabei an folgendem Problem zu verzweifeln, ich hoffe Ihr könnt mir helfen.
Ich habe recht Viele Textdateien in denen ich ganze Absätze suchen und ersetzen muß. Außerdem muß ich Teile des alten Absatzes in den neuen einbauen.
Also zum Beispiel:

Text
Text
A
A
A ->"Name"
A

soll zu

Text
Text
B ->"Name"
B

werden. "Name" steht dabei immer für etwas anderes. Das Suchpattern soll also:

A
A
A -> *
A

oder so sein. Mit sed bin ich nicht weitergekommen und ein Bekannter meint mit Perl sollte es gehen...
Besten Dank für eure Hilfe
 
Yep, Perl ist dafür geeignet. Dein Beispiel lässt sich mit

Code:
perl -pi -e 's/Text\nText\nA\nA\nA ->"Name"\nA/Text\nText\nB ->"Name"\nB/g' file

erschlagen. Dabei sorgt "-0\777" dafür, dass Perl das File als ein String einliest. Deswegen darf das File nicht zu gross sein (ein paar MB). "\n" entspricht dem Newline an jedem Zeilenende.

Gruss, Xanti
 
Danke für die schnelle Antwort! So ganz habe ich es nocht nicht verstanden.

Mit "Name" meine ich eigentlich das in den jweiligen Textdateien dafür immer etwas anderes steht was in den neuen Absatz übernommen werden soll. Kann ich bei Perl mit den "normalen" bash regular expressions arbeiten? Also so etwas wie

perl -pi -e 's/Text\nText\nA\nA\nA ->"(.*)"\nA/Text\nText\nB ->"\1"\nB/g' file

Muß ich bei Perl Sonderzeichen auch mit einem \ versehen (etwas \[ für [)?
 
Im Grunde schon, obwohl die Bash-Regexps eher von Perl abstammen. Dein Beispiel ist syntaktisch richtig. Falls Name über mehrere Zeilen geht, solltest Du die Option /s zusätzlich (also /gs statt /g) wählen, damit "." auch "\n" matcht. Folgende Sonderzeichen haben eine Sonderfunktion beim Matchen und müssen deswegen "escaped" werden: +?.*^$()[{|\

Gruss, Xanti
 
Besten Dank! Ich werds gleich morgen in der Uni testen.
 
Hallo
Geht auch mit sed :D

wolle@Nietzsche:~/temp
$ cat testfile
text
mehr text mit umbruch

A
A
A->Namea
A
mehr text
noch mehr text
A
A->Namea
text
text

wolle@Nietzsche:~/temp
$ sed -ne '/^A\|A->.*$/!p;/^A\|A->.*$/{s/\(A->.*\)$/B->NameB/g;s/A/B/;p}' testfile
text
mehr text mit umbruch

B
B
B->NameB
B
mehr text
noch mehr text
B
B->NameB
text
text
wolle@Nietzsche:~/temp
sed --version
GNU sed Version 4.1.4
Copyright (C) 2003 Free Software Foundation, Inc.

Wenn du GNU sed hast, kennt auch sed die Option -i um die datei direkt zu editieren.
Mit perl ist die Lösung aber für kleine Dateien besser, da du dort auch ein Backup angeben kannst.
Bei großen Dateien geht es auch mit sed.
Hast du kein GNU sed , bau dir eine einfache Schleife drum und arbeite mit Umleitung.
Code:
for I in $(find -iname "name*"); do sed -ne '...' $I > $I_output&& cat $I_output >$I; done

oder mit while read oder oder...;)
HTH
Gruß Wolfgang

Edit// Sed noch etwas verbessert,damit Namea nicht feststeht und nur A am Anfang verändert wird, nicht aber in der Zeilenmitte.
 
Zuletzt bearbeitet:
Hallo, muss nochmal nerven...

hollstei@george:~> cat ptest
Text
Name
Neu
hollstei@george:~> perl -pi -e 's/Text\nName/Tux\nTux/g' ptest
hollstei@george:~> cat ptest
Text
Name
Neu
hollstei@george:~>

Wieso funktioniert das nicht? Ich wollte ersteinmal ein einfachen Test machen...
Beste Gruesse Andre
 
Weil ich oben die Option "-0\777" vergessen habe. Dabei hab ich sie erklärt...:think:

Egal, der Befehl müsste

Code:
perl -0\777 -pi -e 's/Text\nName/Tux\nTux/g' ptest

lauten. Normalerweise liest Perl Zeile für Zeile und kann deswegen Suchmuster, die über mehrere Zeilen gehen, nicht matchen. Mit der Option "-0\777" wird das File als ein grosser String eingelesen. Nachteil ist, dass das File nicht zu gross sein darf. Dann ist Wolfgangs Vorschlag mit sed zu bevorzugen.

Gruss, Xanti
 

Ähnliche Themen

[Gelöst] Suchen und ersetzen mit Hilfe mehrerer Parameter

/home von sda auf andere Partition umziehen

rsnapshot und ein Rechteproblem?

Squid als RPCoHTTPS Proxy für Outlook Anywhere

script um logfile zu monitoren/anzupassen

Zurück
Oben