zebulon-ufh
Anmeldungsdatum: 12. Dezember 2016
Beiträge: 50
|
Moins! und zwar nur vor der ersten! Und da breche ich mir einen ab. Konkret handelt es sich um eine Datei, die in etwa folgenden Aufbau hat: Header
Header
Header
Body
Body
Body
Body
Body
Signature Draus werden soll: Header
Header
Header
Additional Header
Body
Body
Body
Body
Body
Signature Draus wird aber per sed 's/^$/Additional Header\n/' ein: Header
Header
Header
Additional Header
Body
Body
Body
Additional Header
Body
Body
Additional Header
Signature sed schreibt also vor jede Leerzeile den zusätzlichen Text, er soll aber nur vor die erste Jemand ne Idee?
|
track
Anmeldungsdatum: 26. Juni 2008
Beiträge: 7174
Wohnort: Wolfen (S-A)
|
Muss es unbedingt sed sein ? - Das Problem ist nämlich: Du musst nach dem Ersetzen umschalten, damit er danach nur noch alles blind weiterreicht, und nix mehr ersetzt. Solch einen Umschalter (oder sonstwas zum Merken) hat sed aber nicht. Also musst Du dort einen Trick anwenden: Umschalten kannst Du dort nur mit einem Wechsel in einen anderen Zustand, am einfachsten in eine Schleife, in der er nur noch liest und druckt: sed '/^$/{s/^/Additional Header\n/; :l n; bl}' Oder Du nimmst was anderes, das sich die "Zustandsänderung" in einer Variablen merken kann: awk '/^$/{if(! gehabt) {print "Additional Header"; gehabt=1}} {print}'
LG, track
|
ADDB
Anmeldungsdatum: 11. Mai 2017
Beiträge: Zähle...
|
In diesem Fall sollte meines Wissens ein einfaches |head -1 genügen:
| sed 's/^$/Additional Header\n/' | head -1
|
Das sollte nur den Obersten Prozess bearbeiten und dann aufhören.
Lg ADDB
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 12832
|
ADDB schrieb: In diesem Fall sollte meines Wissens ein einfaches |head -1 genügen:
| sed 's/^$/Additional Header\n/' | head -1
|
Das sollte nur den Obersten Prozess bearbeiten und dann aufhören.
Was auch immer Du mit "Obersten Prozess" meinst. Dein Vorschlag ist keine Lösung für das dargestellte Problem.
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 12832
|
track schrieb: Muss es unbedingt sed sein ? - Das Problem ist nämlich: Du musst nach dem Ersetzen umschalten, damit er danach nur noch alles blind weiterreicht, und nix mehr ersetzt.
Ich habe tatsächlich noch eine andere Lösung mit sed gefunden: 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 | $ cat file
aaaa
aaaa
bbbb
bbbb
bbbb
cccc
cccc
cccc
$ ( exec 6< file; sed '/^$/ {i\
foo
q
}' <&6; cat <&6 )
aaaa
aaaa
foo
bbbb
bbbb
bbbb
cccc
cccc
cccc
|
☺
Solch einen Umschalter (oder sonstwas zum Merken) hat sed aber nicht.
In meinem Fall ist der Trick, aus einem Dateideskriptor mit sed nur bis zur ersten Einfügung zu lesen. Der Rest wird dann von cat gelesen und nicht geändert.
|
seahawk1986
Anmeldungsdatum: 27. Oktober 2006
Beiträge: 11180
Wohnort: München
|
Man könnte sed auch bis zur ersten leeren Zeile suchen lassen und dort die Ersetzung vornehmen:
| sed '0,/^$/s//Additional Header\n/' file
|
|
track
Anmeldungsdatum: 26. Juni 2008
Beiträge: 7174
Wohnort: Wolfen (S-A)
|
seahawk1986 schrieb: Man könnte sed auch bis zur ersten leeren Zeile suchen lassen und dort die Ersetzung vornehmen:
| sed '0,/^$/s//Additional Header\n/' file
|
👍 Eine solche Lösung mit einer Bereichsangabe (einer typischen Stärke von sed ) hatte ich gesucht, und war nicht drauf gekommen. Interessant ist auch, dass die leere Regex tatsächlich nur die leere Zeile erkennt. Den kannte ich auch noch nicht. (nochmals 👍 !) LG, track
|
seahawk1986
Anmeldungsdatum: 27. Oktober 2006
Beiträge: 11180
Wohnort: München
|
track schrieb: Interessant ist auch, dass die leere Regex tatsächlich nur die leere Zeile erkennt. Den kannte ich auch noch nicht. (nochmals 👍 !)
Wenn man bei sed (oder z.B. auch bei den ex Befehlen in vim) das Muster für die Suche leer lässt, wiederholt er das zuletzt davor genutzte Muster - das ist effektiv eine Kurzform von
| sed '0,/^$/s/^$/Additional Header\n/' file
|
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 12832
|
rklm schrieb:
In meinem Fall ist der Trick, aus einem Dateideskriptor mit sed nur bis zur ersten Einfügung zu lesen. Der Rest wird dann von cat gelesen und nicht geändert.
Zu umständlich realisiert: so ist es einfacher:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 | $ ( sed '/^$/ {i\
foo
q
}'; cat ) <file
aaaa
aaaa
foo
bbbb
bbbb
bbbb
cccc
cccc
cccc
|
seahawk1986 schrieb: Man könnte sed auch bis zur ersten leeren Zeile suchen lassen und dort die Ersetzung vornehmen:
| sed '0,/^$/s//Additional Header\n/' file
|
👍 Wieder was über sed gelernt (Bedeutung von Adresse 0 und s//).
|
zebulon-ufh
(Themenstarter)
Anmeldungsdatum: 12. Dezember 2016
Beiträge: 50
|
seahawk1986 schrieb: Man könnte sed auch bis zur ersten leeren Zeile suchen lassen und dort die Ersetzung vornehmen:
| sed '0,/^$/s//Additional Header\n/' file
|
Sorry, daß ich erst jetzt wieder einsteige. Ich war felsenfest der Meinung, per Mail über Antworten benachrichtigt zu werden. Erst jetzt bin ich durch Zufall (ich hätte da nämlich noch ein Problem. Extra Thread dazu kommt) hier drauf gestoßen. Leider bekomme ich mit dem Tipp die Fehlermeldung "sed: -e Ausdruck #1, Zeichen 38: Nicht beendeter s'-Befehl".
Müsste da eventuell das Leerzeichen in "Additional Header" ausmaskiert werden?
TIA.
Ulrich
|
seahawk1986
Anmeldungsdatum: 27. Oktober 2006
Beiträge: 11180
Wohnort: München
|
Leerzeichen im Ersetzungsteil muss man nicht maskieren - den genannten Fehler kann ich auch nicht nachvollziehen - hast du eventuell irgendwo einen Tippfehler rein gebracht?
me@PreciseVM:/tmp$ apt-cache policy sed
sed:
Installiert: 4.2.1-9
Kandidat: 4.2.1-9
Versionstabelle:
*** 4.2.1-9 0
500 http://de.archive.ubuntu.com/ubuntu/ precise/main amd64 Packages
100 /var/lib/dpkg/status
me@PreciseVM:/tmp$ cat test.txt
Header
Header
Header
Body
Body
Body
Body
Body
me@PreciseVM:/tmp$ sed '0,/^$/s//Additional Header\n/' test.txt
Header
Header
Header
Additional Header
Body
Body
Body
Body
Body
|
zebulon-ufh
(Themenstarter)
Anmeldungsdatum: 12. Dezember 2016
Beiträge: 50
|
seahawk1986 schrieb: Leerzeichen im Ersetzungsteil muss man nicht maskieren - den genannten Fehler kann ich auch nicht nachvollziehen - hast du eventuell irgendwo einen Tippfehler rein gebracht?
Im Gegenteil #-) Ich hätte es besser abtippen sollen, statt es per Copypaste aus dem Tipp hier zu holen. Die scheint was mitkopiert zu haben, was der sed nicht mochte. "Zu Fuß" eingetippt geht es ohne Fehlermeldung. Eine kleine Hürde galt es noch zu umschiffen: Die zu behandelnde Datei wurde unter Wine von einer Windows-Applikation erstellt. Und da ist nunmal eine Leerzeile nicht leer (^$), sondern enthält aus Sicht des Pinguins ein "\r". Mit dem Pattern ^\r$ klappt's jetzt. Danke an Alle!
|