[gelöst] sed: Zeile isolieren und bearbeiten
[gelöst] sed: Zeile isolieren und bearbeiten
Ich möchte nach dem 1. Auftreten meines Suchbegriffes die Weiterverarbeitung
der Datei beenden und nur die gefundene Zeile bearbeiten.
Warum funktioniert das nicht:
(in der 3. Zeile 'ccdcc' das d durch f ersetzen)
x="aabaa\nbbcbb\nccdcc\nddedd"
echo -e $x | sed -e '/ccdcc/q; $!d; s/d/f/'
Ausgabe: 'ccdcc'
mit
echo -e $x | sed -e '/ccdcc/q; $!d'
wird die Zeile zwar isoliert, aber die Weiterverarbeitung mit
s/d/f/
klappt nicht, warum?
Funktionieren tuts so:
echo -e $x | sed -e '/ccdcc/q; $!d' | sed -e 's/d/f/'
Ausgabe: 'ccfcc'
Kann mir das mal jemand erklären...
der Datei beenden und nur die gefundene Zeile bearbeiten.
Warum funktioniert das nicht:
(in der 3. Zeile 'ccdcc' das d durch f ersetzen)
x="aabaa\nbbcbb\nccdcc\nddedd"
echo -e $x | sed -e '/ccdcc/q; $!d; s/d/f/'
Ausgabe: 'ccdcc'
mit
echo -e $x | sed -e '/ccdcc/q; $!d'
wird die Zeile zwar isoliert, aber die Weiterverarbeitung mit
s/d/f/
klappt nicht, warum?
Funktionieren tuts so:
echo -e $x | sed -e '/ccdcc/q; $!d' | sed -e 's/d/f/'
Ausgabe: 'ccfcc'
Kann mir das mal jemand erklären...
Zuletzt geändert von detix am 19.01.2008 22:25:01, insgesamt 1-mal geändert.
Gruß an alle Debianer, und immer daran denken:
Macht ohne Haftung funktioniert nicht!
Macht ohne Haftung funktioniert nicht!
Re: sed: Zeile isolieren und bearbeiten
Aber das ist doch logisch, denn das Script macht genau was du sagst .... nur sagst du nicht das was du willstdetix hat geschrieben:Ich möchte nach dem 1. Auftreten meines Suchbegriffes die Weiterverarbeitung
der Datei beenden und nur die gefundene Zeile bearbeiten.
Warum funktioniert das nicht:
(in der 3. Zeile 'ccdcc' das d durch f ersetzen)
x="aabaa\nbbcbb\nccdcc\nddedd"
echo -e $x | sed -e '/ccdcc/q; $!d; s/d/f/'
Ausgabe: 'ccdcc'
mit
echo -e $x | sed -e '/ccdcc/q; $!d'
wird die Zeile zwar isoliert, aber die Weiterverarbeitung mit
s/d/f/
klappt nicht, warum?
Du sagst: wenn 'ccdcc' gefunden wurde, soll beendet werden ... nun, das genau tut es.
Dass es hier funktioniert liegt genau an dem was ich oben beschrieben habe: Das erste SED-Script wird abgebrochen nachdem 'ccdcc' gefunden und ausgegeben wurde. Danach wird die Ausgabe mit dem zweiten SED-Aufruf bearbeitet.Funktionieren tuts so:
echo -e $x | sed -e '/ccdcc/q; $!d' | sed -e 's/d/f/'
Ausgabe: 'ccfcc'
Kann mir das mal jemand erklären...
verstanden?
Use ed once in a while!
Ich hab gerade kein Linux zur Hand, aber müsste nicht auch ein funktionieren?
Code: Alles auswählen
sed -e '/ccdcc/{s/d/f/;q;}'
Re: sed: Zeile isolieren und bearbeiten
daraus würde ich folgendes machen:detix hat geschrieben: echo -e $x | sed -e '/ccdcc/q; $!d' '
Code: Alles auswählen
echo -e $x | sed '/ccdcc/!d'
Die Erklärung hatte Meillo genannt.
Gruß fuzzy
Re: sed: Zeile isolieren und bearbeiten
Das funktioniert nicht, weil dadurch alle Vorkommen und nicht nur das erste ausgegeben werden.fuzzy hat geschrieben:daraus würde ich folgendes machen:detix hat geschrieben: echo -e $x | sed -e '/ccdcc/q; $!d' 'Code: Alles auswählen
echo -e $x | sed '/ccdcc/!d'
Statt
Code: Alles auswählen
x="aabaa\nbbcbb\nccdcc\nddedd"
Code: Alles auswählen
x="aabaa
bbcbb
ccdcc
ddedd"
guter Tipp!Joghurt hat geschrieben:Ich hab gerade kein Linux zur Hand, aber müsste nicht auch ein
Code:
sed -e '/ccdcc/{s/d/f/;q;}'
funktionieren?
Ich komme zu folgender Lösung:
Code: Alles auswählen
echo -e $x | sed -n '/ccdcc/{s/d/f/; p; q;}'
Use ed once in a while!
Also, wenn ich das richtig verstehe wird nach 'q' alle weitere Verarbeitung abgebrochen.
Wenn das so ist, hab ichs verstanden
Wesentlich besser als mein Sch... ist der Vorschlag von Joghurt
sed -e '/ccdcc/{s/d/f/;q;}'
geht so zwar nicht, aber Meillos Korrektur
sed -n '/ccdcc/{s/d/f/; p; q;}'
funktioniert richtig, habs jetzt so gemacht
sed -ne '/ccdcc/{s/d/f/p;q;}'
Vielen Dank für die umfassenden Informationen.
Wenn das so ist, hab ichs verstanden
Wesentlich besser als mein Sch... ist der Vorschlag von Joghurt
sed -e '/ccdcc/{s/d/f/;q;}'
geht so zwar nicht, aber Meillos Korrektur
sed -n '/ccdcc/{s/d/f/; p; q;}'
funktioniert richtig, habs jetzt so gemacht
sed -ne '/ccdcc/{s/d/f/p;q;}'
Vielen Dank für die umfassenden Informationen.
Gruß an alle Debianer, und immer daran denken:
Macht ohne Haftung funktioniert nicht!
Macht ohne Haftung funktioniert nicht!
ja.detix hat geschrieben:Also, wenn ich das richtig verstehe wird nach 'q' alle weitere Verarbeitung abgebrochen.
Wenn das so ist, hab ichs verstanden
Sehr gerne!Vielen Dank für die umfassenden Informationen.
... denn irgendwie freue ich mich immer, wenn jemand ein Problem mit sed hat und ich dadurch mal wieder damit arbeiten darf. Sonst passiert das leider viel zu selten.
Use ed once in a while!
Eine Frage muß ich aber noch hinterherschieben...
Wie sieht es aus, wenn ich nur die 2te Fundstelle isolieren und bearbeiten will?
Wäre ja zu schön gewesen wenn das funktioniert:
x="aabaa\nbbcbb\nccdcca\nddedd\nccdccb\nccdccd"
echo -e $x | sed -ne '/ccdcc/{s/d/f/2p;q;}'
tuts aber leider nicht, '2p' bezieht sich auf die gesamte "Textdatei"
und nicht nur auf die Zeilen die den Suchbegriff enthalten,
wie muß ich es erweitern damit auch Das klappt?
Wie sieht es aus, wenn ich nur die 2te Fundstelle isolieren und bearbeiten will?
Wäre ja zu schön gewesen wenn das funktioniert:
x="aabaa\nbbcbb\nccdcca\nddedd\nccdccb\nccdccd"
echo -e $x | sed -ne '/ccdcc/{s/d/f/2p;q;}'
tuts aber leider nicht, '2p' bezieht sich auf die gesamte "Textdatei"
und nicht nur auf die Zeilen die den Suchbegriff enthalten,
wie muß ich es erweitern damit auch Das klappt?
Gruß an alle Debianer, und immer daran denken:
Macht ohne Haftung funktioniert nicht!
Macht ohne Haftung funktioniert nicht!
Keine schöne Lösung, aber ich würde einfach beim ersten Durchlauf die Zeile mit dem ersten Vorkommen nicht ausgeben .... und dann im zweiten sed-Aufruf wie gewohnt agieren.detix hat geschrieben:Eine Frage muß ich aber noch hinterherschieben...
Wie sieht es aus, wenn ich nur die 2te Fundstelle isolieren und bearbeiten will?
... das ist mir jedenfalls auf die Schnelle eingefallen. Ob es auch wirklich gute Lösungen mit sed gibt (geben kann) kann ich nicht sagen. Aber vielleicht soviel: sed bearbeitet (wie der Name schon sagt) Streams (Dateien zeilenweise). Variablen, die mitzählen wie viele Vorkommen des Suchbegriffs schon waren, sind nicht vorhanden .... dafür müsstest du dann AWK nehmen, das ist eine richtige Programmiersprache.
Was mir aber beim Schreiben noch einfällt: Wenn es eine Möglichkeit (Switch) gibt, die komplette Datei (und nicht zeilenweise) zu matchen, dann könntest du so etwas wie '/hallo.*hallo/' machen ...
Use ed once in a while!
Mittlerweile habe ich die halbe bash_history mit sed Versuchen zugepflastert,
Ergebnis = Null. Mit echo und awk komme ich zu dieser Lösung,
um die 2., 3. oder sonstige Fundstelle zu isolieren und bearbeiten, hier die 2te:
Wen es interessiert, mit
sed -ne /ccdcc/= _111
werden nur die Zeilennummern der Fundstellen ausgegeben, leider in seperaten Zeilen.
Dies wird verhindert mit einem echo drumherum
echo $(sed -ne /ccdcc/= _111)
Nun kann der String nach awk weitergeleitet werden, der dann nur das 2te Wort,
(= die 2te Fundstelle) ausgibt
echo $(sed -ne /ccdcc/= _111) | awk '{print $2}'
und das Ganze wird in die Variable x geschrieben, mit
sed -ne "$x s/d/f/p" _111
wird dann nur in dieser Zeile (hier die 5te) gesucht, ersetzt und ausgegeben.
Vielleicht nicht die beste Lösung, aber auf jeden Fall eine die ich noch durchschaue.
Vielen Dank an Alle
Ergebnis = Null. Mit echo und awk komme ich zu dieser Lösung,
um die 2., 3. oder sonstige Fundstelle zu isolieren und bearbeiten, hier die 2te:
Code: Alles auswählen
echo -e "aabaa\nbbcbb\nccdcca\nddedd\nccdccb\nccdccd" >_111
x=$(echo $(sed -ne /ccdcc/= _111) | awk '{print $2}')
sed -n "$x s/d/f/p" _111
sed -ne /ccdcc/= _111
werden nur die Zeilennummern der Fundstellen ausgegeben, leider in seperaten Zeilen.
Dies wird verhindert mit einem echo drumherum
echo $(sed -ne /ccdcc/= _111)
Nun kann der String nach awk weitergeleitet werden, der dann nur das 2te Wort,
(= die 2te Fundstelle) ausgibt
echo $(sed -ne /ccdcc/= _111) | awk '{print $2}'
und das Ganze wird in die Variable x geschrieben, mit
sed -ne "$x s/d/f/p" _111
wird dann nur in dieser Zeile (hier die 5te) gesucht, ersetzt und ausgegeben.
Vielleicht nicht die beste Lösung, aber auf jeden Fall eine die ich noch durchschaue.
Vielen Dank an Alle
Gruß an alle Debianer, und immer daran denken:
Macht ohne Haftung funktioniert nicht!
Macht ohne Haftung funktioniert nicht!