# sed-Wissen aus der Praxis für Noobs und Geeks

## qp

*edit* div. Threads zusammengeführt und Titel verallgemeinert --think4urs11

data.txt :

1 kirk

2 worf

3 spock

4 data

5 odo

6 kira

7 enterprise

8 chekov

9 riker

10 sulu

------ EOF----------

SED -n -e '/o/, /a/p' data.txt

Eigentlich sollte es von der 1.Zeile mit 'o' bis 1.Zeile mit 'a' ausgeben.

Also :

2 worf

3 spock

4 data

Aber die Ausgabe ist :

2 worf

3 spock

4 data

5 odo

6 kira

8 chekov

9 riker

10 sulu

Wieso?   :Confused: 

Danke im voraus!!!

----------

## think4urs11

deutsch nur in den deutschen Foren, daher 'moved from Portage & Programming to Diskussionsforum'

----------

## Fauli

 *qp wrote:*   

> SED -n -e '/o/, /a/p' data.txt

 

Wenn sed das a gefunden hat, fängt es wieder von Neuem an, nach dem o zu suchen.

----------

## qp

Ok, ich hab es schon geahnt... danke für die Antwort...

Und wie kann ich das unterdrücken, nämlich, dass SED genau

das erste Auftreten dieses Bereiches ausgibt? Ich hab probiert mit 'q', aber

klappt nicht so richtig...

----------

## think4urs11

```
 sed '/o/!d;:loop;N;/a/!b loop;q' data.txt
```

----------

## qp

sed -n "/^[^oe]*$/p" data.txt

was macht diese Zeile genau??

/^[^oe]*/  bedeutet : es sollen keine e oder o (in beliebiger Menge) am Anfang der Zeile

stehen...

/^[^oe]*$/ heisst es nun, dass alles sich auf die letzte Zeile beziehen muss?

irgendwie verstehe ich es nicht..

Hat jemand eine Idee?

Danke im voraus!

----------

## think4urs11

im Zweifelsfall hilft einfach ausprobieren  :Wink: 

Dein Kommando gibt nur noch Zeilen aus in denen weder ein o noch ein e vorkommen.

----------

## qp

ja klar, das kann man durch ausprobieren finden...

aber ich will die logik verstehen, die dahinter steht...

irgendwie ist es unlogisch - wozu sind erstes ^ und $ am Ende?

das ganze verwirrt sehr stark..  :Shocked: 

----------

## think4urs11

dir ist aber schon bewußt das hier das Gentooforum ist und nicht das fuer anonyme sed-geeks (wie mich)?  :Wink: 

...mein ja nur da deine Posts im Forum der letzten beiden Tage bisher außer sed eigentlich nur sed und gelegentlich sed zum Thema hatten...

lies dich mal durch ein paar howtos, z.B.

http://sed.sourceforge.net/ oder http://www-128.ibm.com/developerworks/linux/library/l-sed1.html

----------

## qp

@Think4UrS11

Danke für den Hinweis!  :Wink: 

Ich bin extra auf Gentoo-Forum gekommen, weil ich aus meiner Erfahrung eindeutig

sagen kann :  Unter Gentoo-People gibt's am meisten Hacker. Also wenn nicht 

Gentoo-Forum, dann wer? :O

----------

## think4urs11

 *qp wrote:*   

> Also wenn nicht Gentoo-Forum, dann wer? :O

 

Ok, DAS Argument lasse ich gelten  :Smile: 

----------

## Ampheus

Danke für den Link.

Will mich endlich mal richtig mit sed befassen  :Smile: 

Achja, das Lob von qp nehme ich natürlich auch gerne an  :Very Happy: 

----------

## nikaya

Das Sed by example ist übrigens von drobbins.  :Wink: 

----------

## think4urs11

 *Ampheus wrote:*   

> Will mich endlich mal richtig mit sed befassen

 

Sehr löblich, sed ist was sehr feines; kommt selten vor das es mit sed nun wirklich nicht mehr geht.

Abschreckende Beispiele gefällig? 1, 2  :Cool: 

 *Ampheus wrote:*   

> Danke für den Link.

  *john.doe wrote:*   

> Das Sed by example ist übrigens von drobbins.

 

Eine leicht variierte Fassung der IBM-Artikel zu sed gibt es auch auf der Gentoo-HP bei den Dokumentationen; Abschnitt DeveloperWorks-Artikel, neben feinen Sachen zu awk, ssh key-Mgmt. und haste-nich-gesehen...

noch ein anderes howto: http://www.linux-fuer-alle.de/doc_show.php?docid=181&catid=8

----------

## Ampheus

Meine Güte, wie lange arbeitest du schon mit sed?

Das Programm ist ja dermaßen mächtig...

Leider wirkt das auf mich immer sehr kryptisch  :Smile: 

Naja da muss ich durch....

----------

## Fauli

Ich weiß nicht, ob diese Skript-Sammlung schon in einer der oben verlinkten Seiten erwähnt wird, aber dort gibt's auch jede Menge Skripts von "basic" bis "extreme", inkl. Sokoban-Spiel.

----------

## sirro

Hier ist ja mindestens ein sed-experte anwesend, darum stelle ich auch mal eine Frage:

```
#echo 'yyy zzz yyy' | sed -re 's#.*(zzz)?.*#xxx \1 xxx#;'

xxx  xxx
```

Wie bekomme ich es hin, dass er den optionalen Teil der RE mit ersetzt?

Also ein $BLACKMAGIC, so dass folgendes gilt:

```
#echo 'yyy zzz yyy' | sed -re $BLACKMAGIC

xxx zzz xxx
```

----------

## think4urs11

meinst du das? 

```
$ echo "yyy zzz yyy" | sed 's/yyy/xxx/g'

xxx zzz xxx
```

----------

## sirro

Ne. Das Beispiel ist natuerlich vereinfacht.

Beispiel: Ich will aus einem User-Agent mehrere Angaben rausziehen, die aber variieren koennen.

```
SonyEricssonK750i/R1L Browser/SEMC-Browser/4Profile/MIDP-2.0 Configuration/CLDC-1.1

SonyEricssonM600i/R100 Mozilla/4.0 (compatible; MSIE 6.0; Symbian OS; 513) Opera 8.65 [en]
```

"SonyEricsson" ist bei allen gleich, darauf folgt das Modell. Soweit so einfach.

Allerdings hat nicht jedes Modell auch Symbian und Opera. Also will ich eine RE, die mir den Agent durch den Modell-Namen ersetzt und falls vorhanden auch noch die Angaben, dass es ein Symbian ist oder einen Opera-Browser benutzt.

Mit mehreren Ausdruecken (fuer jeden moeglichen Fall eine) ist das natuerlich kein Problem, aber das ist ja die unelegante Methode.  :Smile: 

Ergebnis soll also etwas aehnliches sein wie:

```
M600i (Symbian OS; Opera 8.65)

SonyEricssonK750i ()
```

----------

## Ampheus

hehe dann möchte ich auch nochmal  :Smile: 

```
sed -e 's/<? /<?php /' -e 's/<?[^php]/<?php /' test.txt | less
```

test.txt:

```
<?foo

<? foo

<?php foo
```

Leider funktioniert es nicht ganz, da bei der ersten Zeile zwar der String richtig ersetzt wird, aber der darauffolgende um 1 Zeichen gekürzt wird.

Also so siehts dann aus:

```
<?php oo

<?php foo

<?php foo
```

----------

## sirro

 *Ampheus wrote:*   

> s/<?[^php]/<?php /'

 

Das funktioniert so nicht. 

Das fette sagt, dass auf "<?" EIN zeichen folgt, dass weder 'p' noch 'h' ist. Da trifft auf deine erste Zeile zu, da 'f' weder 'p' noch 'h' ist also wird es mit <?php ersetzt.

Was du wahrscheinlich willst ist, dass der ganze ausdruck !="php" gematcht wird. Bisher habe ich da noch keine andere Loesung gesehen als die Zeichen aufwaendig einzeln in der Reihenfolge zu matchen und dann spaeter mit \1 wieder einsetzen: [^p][^h][^p]. Bei 3 Buchstaben ist das zwar nicht mehr uebersichtlich aber der overhead haelt sich in grenzen.

Evtl. geht es aber auch noch anders  :Wink: 

```
sed -e 's/<? /<?php /' -e 's/<?\([^p][^h][^p]\)/<?php \1/' test.txt
```

----------

## Ampheus

Ah danke, die \1 hat mir geholfen  :Smile: 

----------

## think4urs11

@sirro:

'n quickhack; weder elegant noch schön aber funktioniert   :Rolling Eyes: 

```
sed 'G;s/ /\n/g' agent.log | sed '/Symbian/{N;s/\n/ /;b};/Opera/{N;s/\n/ /;b}' | sed '/Sony\|Symbian\|Opera/b;d' | sed 's/^SonyEricsson\(.*\)$/\n\1/' | sed '/^$/b;:x;$!N;s/\n\(.\)/ \1/;t x'
```

----------

## sirro

Immerhin  :Smile: 

Aber da das in einer einzigen langen sed-Datei ist komme ich mit einem grep zwischendurch auch nicht weiter.

Hab jetzt einfach zwei Zeilen draus gemacht und nur nach Opera abgefragt, das muss reichen.

----------

## think4urs11

geht auch ganz ohne grep - hab es oben korrigiert  :Wink: 

----------

## think4urs11

anderer Ansatz, keine Pipes mehr

```
sed -e 's/SonyEricsson/_-_/;s/_-_\([^\/]*\).*\(Symbian[^;]*\).*\(Opera [^ ]*\).*/\1 (\2; \3)/;s/_-_\([^\/]*\).*\(Opera [^ ]*\).*/\1 (\2)/;s/_-_\([^\/]*\).*\(Symbian[^;)]*\).*/\1 (\2)/;s/_-_\([^\/]*\).*/\1 (-)/' agent.log
```

----------

## sirro

Ich hab das gefühl das lässt dir keine Ruhe  :Smile: 

Danke, das ist zwar laenger als ich erwartet hatte, aber es macht das richtige.

----------

## Ampheus

Nenn den Thrad am besten doch"Der sed-Thread"  :Smile: 

Was hier mittlerweile alles gesammelt wird....

Und dann stellen wir hier unsere sed-Fragen, oder wir machen Spiel daraus  :Smile: 

----------

## think4urs11

 *Ampheus wrote:*   

> Nenn den Thrad am besten doch"Der sed-Thread"

 

Manchmal werden Wünsche erfüllt....  :Smile: 

Ein Sammelthread erscheint mir sinnvoller als diverse verstreute im Forum. Wenn jemand gute Threadkandidaten hat die sich mit 'wie mach ich foo mit sed' beschäftigen kennt verlinke ich die gerne im ersten Post als Referenzen.

----------

## UTgamer

Seit Jahren suche ich eine Lösung für mein Problem, nirgends habe ich eine vollständige Lösung gefunden.

Also es geht um Lesezeichen aus den Mozilla Browsern. Meine Bookmarks.html ist unkorrigiert größer als 3,5 MB.  :Sad: 

Einen Großteil davon sind Einträge die von den Browsern selbst vorgenommen werden wie erster Besuch, letzter Besuch, woher der Verweis kam.

So sehen die orig. Zeilen aus:

```
<A HREF="http://.../" ADD_DATE="1180098314" LAST_VISIT="1183624444" LAST_CHARSET="UTF-8" ID="rdf:#$KR9rE3">
```

Nun möchte ich das in den Verweiszeilen der Datei nur noch 

```
<A HREF="http://.../">
```

 da stehen bleibt.

Nach langer Testzeit habe ich diesen Javascriptcode dafür entwickelt:

```
javascript:(function(){ var ls=document.getElementsByTagName('*'); for (var i=0; i<ls.length; i++) {l=ls[i]; l.removeAttribute('id'); l.removeAttribute('last_charset'); l.removeAttribute('icon'); l.removeAttribute('last_modified'); l.removeAttribute('last_visit'); l.removeAttribute('add_date'); l.removeAttribute('personal_toolbar_folder');} alert('Cleanup Complete - Save as Web Page, Complete')})();
```

Ich lade die zu bearbeitende Datei in das Browserfenster und lasse den Javascriptcode dadrüberlaufen, danach speichere ich die Seite wieder ab.

Also diese Elemente mit ihrem hintenangefügten Code müßen raus:

id

last_charset

icon

last_modified

add_date

Diese Methode hat 2 Fehler. Der 1. Fehler, je nach Javascriptversion muß ich das Script erneut anpassen.

Der 2. Fehler, es kommt vor das auch komplette Links verschwinden. Aus der 3,5 MB bookmarks.html sind ~100 KB an Links komplett entfernt oder einfach leer gemacht worden. Also der Javascriptinterpreter selbst macht Fehler, es verschwinden nämlich vereinzelt auch Überschriften.

Gäbe es eine SED-Lösung die stabiler ist?

----------

## sirro

Wenn wirklich das Format so fest ist, dass immer genau ein <A> pro Zeile ist und href immer der erste, dann ist es IMHO einfach.

```
echo '<A HREF="xxxxxx" ADD_DATE="1180098314" LAST_VISIT="1183624444" LAST_CHARSET="UTF-8" ID="rdf:#$KR9rE3">'|sed -re 's#<A HREF="([^"]+)".*>#<A HREF="\1">#'
```

Kannst du ja erstmal drüberlaufen lassen ohne was zu ändern und gucken was passiert.

Je nachdem muss man das dann noch was verfeinern.

Oder die einzelnen Parameter einzeln filtern.

```
echo '<A HREF="xxxxxx" ADD_DATE="1180098314" LAST_VISIT="1183624444" LAST_CHARSET="UTF-8" ID="rdf:#$KR9rE3">'|sed -re 's#ADD_DATE="[^"]+"##'
```

----------

## UTgamer

 *sirro wrote:*   

> Wenn wirklich das Format so fest ist, dass immer genau ein <A> pro Zeile ist und href immer der erste, dann ist es IMHO einfach.
> 
> ```
> echo '<A HREF="xxxxxx" ADD_DATE="1180098314" LAST_VISIT="1183624444" LAST_CHARSET="UTF-8" ID="rdf:#$KR9rE3">'|sed -re 's#<A HREF="([^"]+)".*>#<A HREF="\1">#'
> ```
> ...

 

Danke, probiere ich gleich mal aus, aber die Werte in den ='...' sind jedesmal andere, mit dieser Methode werde ich genau diesen einen Link erwischen. aber ich schaue jetzt gleich mal nach. Es handelt sich um ~5000 Links mit jeweils anderen Werten in ='...'

[Edit]

Das erste Beispiel sieht so aus als wenn es funktionieren würde ich habe

```
cat bookmarks.html |sed -re 's#<A HREF="([^"]+)".*>#<A HREF="\1">#' > test.html
```

gemacht.

----------

## sirro

Einfach die Ausgabe mit > in eine Datei leiten.

Oder sed mit -i sagen, dass er es direkt in der Datei machen soll. (Sicherheitskopie laesst gruessen  :Smile: )

----------

## UTgamer

[Edit in neuen thread verschoben]

 :Laughing:  Das ging ja echt flink mit dieser Lösung. Daaaaaannnkkkkkeeeee.

[Edit2]

Zu früh gefreut, alle Überschriften sind mit weg.  :Sad: 

Eine ganze Zeile sieht vollgendermaßen aus:

```
<A HREF="http://ixquick.com/" ADD_DATE="1180098314" LAST_VISIT="1183624444" LAST_CHARSET="UTF-8" ID="rdf:#$KR9rE3">Ixquick Metasuche</A>
```

Ganz hinten der Eintrag hier am Beispiel einer Suchmaschine 

```
...>Ixquick Metasuche</A>
```

 den hatte ich im oberen Beispiel leider vergessen anzufügen.

----------

## sirro

```
echo '<A HREF="xxxxxx" ADD_DATE="1180098314" LAST_VISIT="1183624444" LAST_CHARSET="UTF-8" ID="rdf:#$KR9rE3">yyyyy</A>'|sed -re 's#<A HREF="([^"]+)"[^>]*>#<A HREF="\1">#'
```

Mit der Variante bekommst du Probleme wenn ein '>' in den Parametern auftaucht, was evtl. in der ID passieren koennte. Darum würde ich ID vorher ausfiltern:

```
echo '<A HREF="xxxxxx" ADD_DATE="1180098314" LAST_VISIT="1183624444" LAST_CHARSET="UTF-8" ID="rdf:#$KR9r>3">yyyyy</A>'|sed -re 's#ID="[^"]+"##; s#<A HREF="([^"]+)"[^>]*>#<A HREF="\1">#'
```

----------

## UTgamer

 *sirro wrote:*   

> 
> 
> ```
> echo '<A HREF="xxxxxx" ADD_DATE="1180098314" LAST_VISIT="1183624444" LAST_CHARSET="UTF-8" ID="rdf:#$KR9rE3">yyyyy</A>'|sed -re 's#<A HREF="([^"]+)"[^>]*>#<A HREF="\1">#'
> ```
> ...

 

Nein das > markiert das Ende eines HTML-Links zwischen > .... und </A>' befindet sich in HTML der anklickbare Linknahme, mit dem ID Feld als letztem oder jenachdem dem ICON Feld als letztem Eintrag sollte dies eigentl. nichts zu tun haben. Also es kann als letztes Feld vor dem > auch das icon -Tag stehen, das ganze ist eine einzige HTML-Zeile.

----------

## sirro

Schon klar.  :Smile: 

Aber wenn du IDs hast IN deren Text zusaetzlich ein > vorkommt, dann macht die erste Loesung Probleme. Die zweite sollte die sicherere sein.

----------

## UTgamer

 *sirro wrote:*   

> Schon klar. 
> 
> Aber wenn du IDs hast IN deren Text zusaetzlich ein > vorkommt, dann macht die erste Loesung Probleme. Die zweite sollte die sicherere sein.

 

Ja echt, der 2. hat funktioniert, vorhin hatte ich noch eine Fehlermeldung bekommen, aber jetzt nicht mehr.

Meinen vorher mit meinem Javascript bereinigten Code habe ich jetzt nochmal nach rund 1 Monat normaler Nutzung wiedermal um rund 500 KB kürzen können, und ich hoffe diesmal sind mir keine Links dabei verloren gegangen.

Also jetzt habe ich "die" funktionierende Lösung, und nun nochmal danke.  :Very Happy: 

[Edit]

Demnächst muß ich wieder mal im Sourcecode von Seamonkey rumwühlen (wäre auch nicht das erste mal, im Chrome Teil kenne ich mich bereits etwas aus). Beim öffnen der bookmarks.html fügt das blöde Ding wieder rund 400KB an ID="rdf:#...." Felder automatisch zu jedem Link dazu. Das ist echt abnormal, die anderen Felder läßt er aber solange unberührt bis ich den Link wieder aufrufe. Also diese Prozedur lasse ich am besten monatlich laufen, solange bis ich die Stelle im Sourcecode gefunden habe um das abzustellen.

[Edit2]

Wer das nachmachen möchte sollte unbedingt ein Backup nutzen. 

Der Ordner: 

```
Ordner "Persönliche Symbolleiste"
```

 wird nach dieser Prozedur nicht mehr erkannt, also hier muß eine kleine Korrektur von Hand erfollgen.  :Wink: 

----------

## think4urs11

 *UTgamer wrote:*   

> Das erste Beispiel sieht so aus als wenn es funktionieren würde ich habe
> 
> ```
> cat bookmarks.html |sed -re 's#<A HREF="([^"]+)".*>#<A HREF="\1">#' > test.html
> ```
> ...

 

igittigitt - useless use of cat   :Arrow:   sed -re 's#<A HREF="([^"]+)".*>#<A HREF="\1">#' bookmarks.html > test.html

 *sirro wrote:*   

> Einfach die Ausgabe mit > in eine Datei leiten.
> 
> Oder sed mit -i sagen, dass er es direkt in der Datei machen soll. (Sicherheitskopie laesst gruessen )

 

Der Vollständigkeit wegen 

```
sed -ibak 's/foo/bar/' some.txt
```

editiert 'inline' some.txt und legt vorher zusätzlich ein Backup some.bak an; ohne Angabe eines Suffixes für ein Backupfile wird auch keines erstellt.

edit: typos korrigiert

----------

## UTgamer

Puuh, Think4UrS11 muß der (heimliche?) Erfinder von SED sein.  :Very Happy: 

Danke, ich werde meine Tipdatenbank damit auffrischen.

Gibst du auch Unterrichtsstunden für SED Newbies, so unter deinen Liebhabern aus dem Forum?   :Embarassed: 

----------

## think4urs11

 *UTgamer wrote:*   

> Puuh, Think4UrS11 muß der (heimliche?) Erfinder von SED sein. 

 

nö, ich lese nur gelegentlich man-pages.

Des weiteren bin ich Admin durch und durch, d.h. stinkfaul (aber geruchsneutral *g*) und genau dafür ist sed gemacht - gemäß der alten Adminregel: 'if you need to do something more than twice - write a script'

Gerade für beispielsweise ein 'ich schick dir die Liste mal als .xls, kannste mal ...' und ähnliche Fälle ist sed genial.

Für die echten Härtefälle in denen ein sed-script dann wirklich mal etwas unübersichtlich werden könnte (nicht so wie in den bisher referenzierten Beispielen) nimmt man dann eben awk/perl, je nach Geschmack.

 *UTgamer wrote:*   

> Du sagmal kann das SED auch etwas nicht?  

 

Ich arbeite noch an einer tageszeitabhängigen Kaffeestärken/Wassermengeneinstellung meiner Koffeinpumpe  :Wink: 

----------

## 3PO

Hallo Zusammen,

ich bräuchte mal nen Tip zu sed.

Nach langem suchen und und experimentieren, habe ich sed nun soweit, das es tut was ich will.

Ich hatte nach einer Möglichkeit gesucht, in einer Datei alle Zeilen zu entfernen, die mit "#" beginnen.

Das geht mit:

```
sed -i Test.abc -e "/^#\.*/d"
```

ganz gut.

So, nun die Fragen:

1.] Gibt es eine Möglichkeit alle Dateien in einen Verzeichnis auf einen Schlag zu durchsuchen? (evtl. auch mit einen kleinen Script?)

2.] Wie kann ich mit sed alle Leerzeilen einer Datei entfernen? (bzw. in allen Dateien eines Verzeichnisses)

Bin über jeden Tipp dankbar.

----------

## sirro

 *3PO wrote:*   

> 1.] Gibt es eine Möglichkeit alle Dateien in einen Verzeichnis auf einen Schlag zu durchsuchen? (evtl. auch mit einen kleinen Script?)

 

Man kann einfach sed auf *, *.txt usw. aufrufen. Oder soll es rekursiv sein?

 *Quote:*   

> 2.] Wie kann ich mit sed alle Leerzeilen einer Datei entfernen? (bzw. in allen Dateien eines Verzeichnisses)

 

Alle Zeilen in denen wirklich nur das Zeilenende steht gehen mit /^$/d weg. (^ für Zeilenanfang kennst du ja schon, $ ist Zeilenende, d löscht)

Es gibt übrigens einen sed-Thread, da solche Fragen offenbar sehr beliebt sind  :Smile: 

----------

## schachti

 *3PO wrote:*   

> 
> 
> 1.] Gibt es eine Möglichkeit alle Dateien in einen Verzeichnis auf einen Schlag zu durchsuchen? (evtl. auch mit einen kleinen Script?)
> 
> 

 

```

for FILE in $(ls VERZEICHNIS); do

  sed -i VERZEICHNIS/"${FILE}" -e "/^#\.*/d"

done

```

 *3PO wrote:*   

> 
> 
> 2.] Wie kann ich mit sed alle Leerzeilen einer Datei entfernen? (bzw. in allen Dateien eines Verzeichnisses)
> 
> 

 

Sollte mit sed "/^$/d" gehen (^ ist der Zeilenanfang, $ das Zeilenende - ^$ sind damit alle Zeilen, bei denen zwischen Zeilenanfang und Zeilenende nichts steht):

```

for FILE in $(ls VERZEICHNIS); do

  sed -i VERZEICHNIS/"${FILE}" -e "/^$/d"

done

```

(bitte erst an Testdaten ausprobieren   :Wink: ).

EDIT: zu langsam.   :Wink: 

----------

## sirro

 *schachti wrote:*   

> for FILE in $(ls VERZEICHNIS); do

 

Sowas kann schnell Probleme machen wenn ls mit Farbe ausgibt. Dann steht z.B. statt "bin" "\033[00m\033[01;34mbin\033[00m" in $FILE.

For kann (zumindest in der Bash) aber einfach direkt auf die Dateien gehen ohne den zusätzlichen ls-Prozess und kürzer

```
for i in /tmp/*; do echo $i; done
```

Bei vielen Befehlen (auch sed) geht es halt noch einfacher: "sed /tmp/*" oder was man halt braucht.

----------

## schachti

 *sirro wrote:*   

>  *schachti wrote:*   for FILE in $(ls VERZEICHNIS); do 
> 
> Sowas kann schnell Probleme machen wenn ls mit Farbe ausgibt. Dann steht z.B. statt "bin" "\033[00m\033[01;34mbin\033[00m" in $FILE.
> 
> 

 

Danke für den Hinweis, das war mir nicht bewusst.

 *sirro wrote:*   

> 
> 
> For kann (zumindest in der Bash) aber einfach direkt auf die Dateien gehen ohne den zusätzlichen ls-Prozess und kürzer
> 
> ```
> ...

 

ok, aber da macht halt wie schon von Dir gesagt die Bash die Arbeit (das Expandieren des *) - wenn man eine Shell hat, die das nicht tut (oder wenn man die Ausgabe von ls vorher mit sed, awk etc. filtern/bearbeiten möchte), kommt man um eine andere Lösung nicht umhin.

----------

## 3PO

Danke erstmal für Antworten, - leider habe ich noch weitere 2 Pribleme:

1.] sed /<Verzeicnis>/*  funftioniert nicht, wenn ich diesem Verzeichnis noch andere Verzeichnisse liegen.

2.] Leider habe ich auch noch Dateien, die keine Extension haben, - d.h. dass z.B. *.txt oder *.* in diesem Fall auch nicht geht.

----------

## think4urs11

ab 3PO hier angehangen

 *3PO wrote:*   

> 1.] sed /<Verzeicnis>/*  funftioniert nicht, wenn ich diesem Verzeichnis noch andere Verzeichnisse liegen.

 

find //kram/blatest -type f -exec sed -i '/bla/d' {} \;

----------

## schachti

In dem Fall sollte es mit meiner Lösung klappen - evtl. musst Du dazu (um das von sirro geschilderte Problem zu umgehen) ls noch um --color=never ergänzen. Falls Du auch Dateien in Unterverzeichnissen mit einbeziehen möchtest, bietet es sich an, find zu benutzen:

```

find VERZEICHNIS -type f -exec sed -i {} -e "/^$/d" \;

```

----------

## 3PO

 *schachti wrote:*   

> .....
> 
>  Falls Du auch Dateien in Unterverzeichnissen mit einbeziehen möchtest, bietet es sich an, find zu benutzen:.....

 

Genau das will ich nicht.   :Laughing: 

----------

## sirro

 *3PO wrote:*   

> 1.] sed /<Verzeicnis>/*  funftioniert nicht, wenn ich diesem Verzeichnis noch andere Verzeichnisse liegen.

 

```
find verzeichnis/ -maxdepth 1 -type f -exec sed -i 's#xxx#test#' {} \;
```

Mit maxdepth kannst du einstellen, dass nur dateien der ersten Ebene des Dateibaums genommen werden falls das gewünscht ist. Falls auch Dateien in Unterverzeichnissen genommen werden sollen einfach das maxdepth weglassen.

-type f sagt, dass nur Dateien genommen werden sollen (keine Verzeichnisse oder anderes)

{} ist die aktuelle Datei.

 *Quote:*   

> 2.] Leider habe ich auch noch Dateien, die keine Extension haben, - d.h. dass z.B. *.txt oder *.* in diesem Fall auch nicht geht.

 

gleicher Anfang des Namens könnte auch helfen, falls du sowas hast. Sonst s.o.

----------

## schachti

ok, dann bietet sich entweder die Variante mit der for-Schleife an,

```

for FILE in $(ls --color=never VERZEICHNIS); do

  sed -i VERZEICHNIS/"${FILE}" -e "/^#\.*/d"

done

```

(die allerdings nicht funktioniert, wenn es Dateinamen gibt, die Leerzeichen enthalten - dann muss man mehr Aufwand treiben), oder Du ergänzt find um -maxdepth 1 (was den Vorteil hast, dass Du weitere Tests, die find bietet (letzter Zugriff, Eigentümer etc.), nutzen kannst, und dass auch Dateien mit Leerzeichen im Namen keine Probleme machen):

```

find VERZEICHNIS -maxdepth 1 -type f -exec sed -i {} -e "/^$/d" \; 

```

EDIT: Es muss -maxdepth 1 heißen, nicht -maxdepth 0.   :Embarassed: 

----------

## think4urs11

 *3PO wrote:*   

> Genau das will ich nicht.  

 

man pages lesen bildet  :Wink: 

find /kram/blatest/ -depth -maxdepth 1 -type f -exec sed -ie 's/bla/blubb/' {} \;

----------

## 3PO

 *Quote:*   

> find /kram/blatest/ -depth -maxdepth 1 -type f -exec sed -ie 's/bla/blubb/' {} \;

 

Jetzt hänge bei -exec   :Crying or Very sad: 

```
find: missing argument to `-exec'
```

 *Quote:*   

> man pages lesen bildet

 

Stimmt !   :Laughing: 

----------

## think4urs11

nach {} muß ein Leerzeichen sein, also {} \ und nicht {}\

----------

## 3PO

Hallo Zusammen,

ich habe folgendes Problem.

Ich habe eine Textdatei, die folgendermasen aufgebaut ist:

```
text1

~irgendwastext1

text2

~irgendwastext2

text3

~irgendwastext3

...usw
```

D.h. jede 2te Zeilen beginnt mit einem "~"

Wie kann ich nun mit z.B. mit sed die Ausgabe ändern in:

```
text1~irgendwastext1

text2~irgendwastext2

text3~irgendwastext3

...usw
```

Geht das überhaupt, und falls ja, wie?

Ich bin über jeden Tipp dankbar.

----------

## think4urs11

meinst du sowas? 

```
sed '$!N;s/\n/ /' inputfile
```

an den sed-Sammelthread angehangen

----------

## firefly

 *Think4UrS11 wrote:*   

> meinst du sowas? 
> 
> ```
> sed '$!N;s/\n/ /' inputfile
> ```
> ...

 

```
eher sed '$!N;s/\n~/ /' inputfile
```

weil sonst hat er alles in einer zeile aber er will ja nur die zeilen mit einer "~" am anfang in die zeile davor "verschieben"

----------

## Finswimmer

```
sed '$!N;s/\n~/~/' t1
```

ergibt:

```
text1~irgendwastext1

text2~irgendwastext2

text3~irgendwastext3

testx

test2

```

Tobi

P.S. Aller guten Dinge sind drei  :Wink: 

----------

## franzf

 *firefly wrote:*   

>  *Think4UrS11 wrote:*   meinst du sowas? 
> 
> ```
> sed '$!N;s/\n/ /' inputfile
> ```
> ...

 

 :Crying or Very sad:  

```
$ eher sed '$!N;s/\n~/ /' inputfile

bash: eher: command not found

```

Und man sollte evtl. noch Leerzeichen am Anfang und Ende jeder Zeile entfernen, sonst gibt es sowas:

```
$ sed '$!N;s/\n//' inputfile

text1 ~irgendwastext1

text2 ~irgendwastext2

text3 ~irgendwastext3

...usw

```

----------

## Finswimmer

Ihr habt immer dann Fehler, wenn es Zeilenanfänge gibt, die nicht mit "~" beginnen. 

Denn die sollen nicht in die vorangehende Zeile rutschen...

Gehe ich jedenfalls von aus  :Wink: 

Tobi

----------

## Finswimmer

Was macht eigentlich dieses $!N;

Tobi

----------

## think4urs11

Die Anforderung war aber 'jede zweite Zeile beginnt mit ~ und soll an die vorherige angehangen werden'; d.h. auf Sonderfälle braucht nicht eingegangen zu werden; von daher war mein Vorschlag schon richtig bis auf den Tippfehler /<space>/ statt richtig //

----------

## Finswimmer

 *Think4UrS11 wrote:*   

> Die Anforderung war aber 'jede zweite Zeile beginnt mit ~ und soll an die vorherige angehangen werden'; d.h. auf Sonderfälle braucht nicht eingegangen zu werden; von daher war mein Vorschlag schon richtig bis auf den Tippfehler /<space>/ statt richtig //

 

Red dich nur raus  :Wink: 

$!N; verstehe ich aber immernoch nicht...

Tobi

----------

## 3PO

 :Arrow:  Danke, hat funktioniert.   :Laughing: 

----------

## 3PO

Und wieder mal eine Frage....   :Laughing: 

Ich möchte aus einer Datei mit folgendem Inhalt, das rot geschriebene entfernen:

 *Quote:*   

> 01000005;0100 0005 (Old) Stream
> 
> 05007C00;0500 007C00 TPS (13E)
> 
> 05008000;0500 008000 (Old) FTC
> ...

 

Ist da sed das Richtige, oder gibt es eine andere Möglichkeit?

----------

## firefly

wenn man die Anforderung, was gelöscht werden soll in einen regulären Ausdruck ausdrücken kann, dann sollte es mit sed und co funktionieren.

EDIT:

hier der reguläre Ausdruck zu deiner Anforderung (ohne die "):

";[0-9]* [0-9]*"

----------

## 3PO

Was ist ein "regulärer Ausdruck"?   :Question: 

----------

## firefly

 *3PO wrote:*   

> Was ist ein "regulärer Ausdruck"?  

 

siehe http://de.wikipedia.org/wiki/Regul%C3%A4rer_Ausdruck

und so sieht dann die sed-zeile aus, mit dem Regulären ausdruck den ich im meinem letzten Post per Edit angegeben habe:

```
sed 's/\;[0-9]* [0-9]*//g'
```

 *test.data wrote:*   

> 01000005;0100 0005 (Old) Stream
> 
> 05007C00;0500 007C00 TPS (13E)
> 
> 05008000;0500 008000 (Old) FTC
> ...

 

Ergebnis:

 *Quote:*   

> 01000005 (Old) Stream
> 
> 05007C00C00 TPS (13E)
> 
> 05008000 (Old) FTC
> ...

 

----------

## sirro

 *firefly wrote:*   

> ";[0-9]* [0-9]*"

 

Im zweiten Teil kommt ein Buchstabe (C) vor. Also eher [0-9C] oder gleich [0-9A-Z]. Kommt halt auf die Quelldaten an.

Besonders viel würde z.B. [^ ] fressen.

----------

## firefly

 *sirro wrote:*   

>  *firefly wrote:*   ";[0-9]* [0-9]*" 
> 
> Im zweiten Teil kommt ein Buchstabe (C) vor. Also eher [0-9C] oder gleich [0-9A-Z]. Kommt halt auf die Quelldaten an.
> 
> Besonders viel würde z.B. [^ ] fressen.

 

ups übersehen, scheinen sich um hex zahlen zu handeln dann wäre 

[0-9A-F] sinnvoller

----------

## 3PO

Lösung gefunden.

so gehts:   :Wink: 

```
sed -e "s/;[0-9A-F]* [0-9A-F]* /; /" -e "s/;[0-9A-F]* /; /"
```

Danke nochmals für die Tipps.   :Wink: 

----------

## firefly

 *3PO wrote:*   

> Lösung gefunden.
> 
> so gehts:  
> 
> ```
> ...

 

also der 2. Ausdruck ist doch unnötig, zu mindestens auf deine Anfangs angegebene Anforderung.

----------

## 3PO

 *firefly wrote:*   

> also der 2. Ausdruck ist doch unnötig, zu mindestens auf deine Anfangs angegebene Anforderung.

 

Das hast du Recht...  :Laughing: 

Allerdings sind auch solche Einträge vorhanden:

```
22000000;2200 Inmedia (5E/60E)

223B0000;223B Bundestag (23E)

22E20000;22E2 National TV (16E)
```

(Habe ich zu spät gesehen...  :Embarassed:  )Last edited by 3PO on Sat Apr 05, 2008 7:48 pm; edited 1 time in total

----------

## firefly

der 2. Ausruck ist unnötig, da der Ausdruck

 *Quote:*   

> [0-9A-F]* [0-9A-F]* 

 

auch deinen 2. Fall

```
22000000;2200 Inmedia (5E/60E)
```

abdeckt.

Denn das * im regulären ausdruck nach den [] steht für 0-n mal sprich eines der Zeichen kommt 0-n mal im gesuchten Ausdruck vor.

EDIT: Ah ok ich habe das letzte leerzeichen in deinen Ausdrücken übersehen.

----------

## 3PO

Hallo Zusammen,

ich habe mal wieder ein Problem.   :Laughing: 

Ich möchte in einer Datei Zeilen suchen lassen die z.B mit: abcd123 beginnen und dann mit einem anderen Eintrag ersetzen.

Ich habe auch schon mit sed experimentiert, jedoch leider erfolglos.   :Crying or Very sad: 

Das Problem ist, dass die Zeilen die ich einfügen möchte, u.U Steuerzeichen enthalten können.

Beispiel:

Suche in Datei blabla.txt nach der Zeile die mit abcd123 beginnt und ersetze diese durch abcd&1$2=3#"$"4

Hat von Euch einer eine Idee, wie man das lösen könnte?

Ich bin über jeden Vorschlag dankbar.

----------

## firefly

durch escapen der steuerzeichen  :Smile: 

```
-> cat blabla.txt 

abcd123

-> sed -e 's/abcd123/abcd\&1\$2\=3#\"\$\"4/g' blabla.txt 

abcd&1$2=3#"$"4
```

----------

## 3PO

 *firefly wrote:*   

> durch escapen der steuerzeichen 
> 
> ```
> -> cat blabla.txt 
> 
> ...

 

Danke @ firefly, das werde ich mal testen.

----------

## musv

 *firefly wrote:*   

> durch escapen der steuerzeichen 
> 
> ```
> -> cat blabla.txt 
> 
> ...

 

Das zeigt Dir die Änderung nur auf dem Bildschirm an. Willst du die Sachen gleich in der Datei ändern: 

```
sed -e 's/abcd123/abcd\&1\$2\=3#\"\$\"4/g' -i blabla.txt
```

----------

## 3PO

 *musv wrote:*   

>  *firefly wrote:*   durch escapen der steuerzeichen 
> 
> ```
> -> cat blabla.txt 
> 
> ...

 

Das hatte noch gefehlt, Danke auch Dir musv.   :Wink: 

----------

## think4urs11

 *musv wrote:*   

> Das zeigt Dir die Änderung nur auf dem Bildschirm an. Willst du die Sachen gleich in der Datei ändern: 
> 
> ```
> sed -e 's/abcd123/abcd\&1\$2\=3#\"\$\"4/g' -i blabla.txt
> ```
> ...

 

und um es vollständig zu machen kann man auch noch automatisch ein Backup mit anlegen:

```
sed -e -i.bak 's/abcd123/abcd\&1\$2\=3#\"\$\"4/g' blabla.txt
```

erstellt automatisch als Backup blabla.txt.bak

obige 5 Beiträge hier angehangen

----------

## 3PO

 *Think4UrS11 wrote:*   

>  *musv wrote:*   Das zeigt Dir die Änderung nur auf dem Bildschirm an. Willst du die Sachen gleich in der Datei ändern: 
> 
> ```
> sed -e 's/abcd123/abcd\&1\$2\=3#\"\$\"4/g' -i blabla.txt
> ```
> ...

 

Das ist ja noch besser...    :Very Happy: 

Perfekt wäre es, wenn ich den roten Teil aus einer extra Datei herausholen könnte.

 *Quote:*   

> sed -e -i.bak 's/abcd123/abcd\&1\$2\=3#\"\$\"4/g' blabla.txt

 

Als z.B. aus einer blabla_2.txt mit dem Inhalt: abcd&1$2=3#"$"4

Das hätte dann den Vorteil, dass man dieses dann im Klartext schreiben könnte, ohne aufpassen zu müssen, das man sich beim "escapen" nicht vertippt.   :Wink: 

----------

## think4urs11

 *3PO wrote:*   

> Perfekt wäre es, wenn ich den roten Teil aus einer extra Datei herausholen könnte. *Quote:*   sed -e -i.bak 's/abcd123/abcd\&1\$2\=3#\"\$\"4/g' blabla.txt 
> 
> Als z.B. aus einer blabla_2.txt mit dem Inhalt: abcd&1$2=3#"$"4Das hätte dann den Vorteil, dass man dieses dann im Klartext schreiben könnte, ohne aufpassen zu müssen, das man sich beim "escapen" nicht vertippt.  

 

Naja das geht schon, in etwa so

```
encoded=$(cat blabla_2.txt | sed 's/\([&"$]\)/\\\1/g')

sed -e -i.bak 's/abcd123/$encoded/g' blabla.txt
```

----------

## 3PO

Jetzt ist es perfekt, thx @ Think4UrS11.   :Very Happy: 

----------

## 3PO

Wie kann ich mit sed in einer Datei alle Zeilen löschen, die mit einem Leerzeichen beginnen?

Leider funktioniert das nicht:   :Crying or Very sad: 

```
sed -i meine_datei.txt -e "/^ \.*/d"
```

----------

## Knieper

Meinst Du mit genau einem Leerzeichen? Und welcher Fall funktioniert nicht? Gib mal ein Beispiel.

----------

## 3PO

 *Knieper wrote:*   

> Meinst Du mit genau einem Leerzeichen? Und welcher Fall funktioniert nicht? Gib mal ein Beispiel.

 

Nun, ich möche in mit sed, oder von mir aus auch mit einen anderen Tool, in eriner Datei alle Zeilen entfernen, die Mit einem Leerzeichen <space> oder evtl. auch mit einen Tabulator <Tab> beginnen.

```
a a a a a a a

   bbbbbbbbb

c   ccc

ddd  d

eeeee

                     ffffff

gg
```

In obigen Beispiel müssten dann die Zeilen "b" und "f" gelöscht werden und das Ergebnis so aussehen:

```
a a a a a a a

c   ccc

ddd  d

eeeee

gg
```

Last edited by 3PO on Fri Oct 03, 2008 12:03 pm; edited 1 time in total

----------

## Knieper

Klappt doch prima?

----------

## 3PO

 *Knieper wrote:*   

> Klappt doch prima?

 

Stimmt...,   :Embarassed:   :Embarassed: 

Ich habe gerade bemerkt, dass das was jetzt noch vorhanden ist überflüssige Zeilenvorschübe sind.

Wie kekomme ich denn die weg?

Also, das rot geschiebene müsste noch weg:

 *Quote:*   

> aaaaa<enter>
> 
> <enter>
> 
> <enter>
> ...

 

----------

## Finswimmer

sed '/^$/d

Das ist ein Kommando, welches die letzten beiden Wünsche zusammenfasst: 

sed '/^[ ]*$/d'

Tobi

----------

## 3PO

 *Finswimmer wrote:*   

> sed '/^$/d
> 
> Das ist ein Kommando, welches die letzten beiden Wünsche zusammenfasst: 
> 
> sed '/^[ ]*$/d'
> ...

 

1000 Dank @ Finswimmer,

Genau das hatte ich gesuchtt.

----------

## slick

So ihr sed-freaks ... habe was für euch. 

Ich möchte in Header einer Mail das erste Auftreten eines bestimmten Musters ersetzen.

Also Beispielswäre wäre die Mail:

```
X-Header-1: foo

X-Header-2: bar

From: Test

To: User

body
```

Ich möchte nun das erste Vorkommen von "X-" im Header ersetzen durch "Y-" Ziel wäre dann

```
Y-Header-1: foo

X-Header-2: bar

From: Test

To: User

body
```

Also, wie stell ichs an?

----------

## firefly

indem du nach dem letzten "/" im sed befehl eine "1" anstelle von "g" angibst.

```
sed -e 's/X\-Header\-2/Y\-Header\-2/1'
```

----------

## Finswimmer

 *firefly wrote:*   

> indem du nach dem letzten "/" im sed befehl eine "1" anstelle von "g" angibst.
> 
> ```
> sed -e 's/X\-Header\-2/Y\-Header\-2/1'
> ```
> ...

 

Warum geht das bei mir nicht? Die Idee hatte ich schon vor 20 min, aber da es nicht ging, wollte ich es nicht posten.

```
$sed -e 's#X#Y#1' mail

Y-Header-1: foo

Y-Header-2: bar

Y-Header-2: bar

Y-Header-2: bar

Y-Header-2: bar

From: Test

To: User

bod

```

----------

## firefly

wiso hast du "#" im ausdruck?

```
-> cat tt

X-Header-1: foo

X-Header-2: bar

From: Test

To: User

body

-> sed -e 's/X\-Header\-2/Y\-Header\-2/1' < tt

X-Header-1: foo

Y-Header-2: bar

From: Test

To: User

body
```

EDIT: ok passt bei mir auch net scheinbar gilt das "1" nur für eine zeile

----------

## slick

Was ist mit dem Fall dass der "X-Header" im Header nicht vorkommt, sondern nur im Body, der aber nicht angefaßt werden soll? Man müßte die Suche bis zu den ersten \n\n einschränken.

----------

## firefly

Jupp das problem ist, das sed default nur eine zeile in seinen buffer schreibt und dann auf diesen die Ersetzung durchführt.

Man kann sed sagen, das er die ganze Datei erst in seinen buffer laden soll, das hat aber den nachteil, dass das  nur mit kleinen Dateien funktioniert.

Eine andere Möglichkeit ist, das sed nach dem 1. finden des gesuchten Ausdrucks die restliche Datei in einer art endlosschleife nur ausgeben soll.

```
sed -e '/X\-Header\-2/{;s/X\-Header\-2/Y\-Header\-2/;:a' '-en;ba' '-e}'
```

Das ganze habe ich hier gefunden: http://www.unix.com/shell-programming-scripting/26562-sed-command-substitue-first-instance-2.html#post302070517

(1. treffer bei google mit folgenden suchworten: sed replace first instance)

----------

## ichbins

und warum nicht einfach sed mit grep bzw grep mit sed kombinieren?

dann kann man doch relativ einfach das erste vorkommen in einer datei rausfinden und ändern.

----------

## think4urs11

 *slick wrote:*   

> Was ist mit dem Fall dass der "X-Header" im Header nicht vorkommt, sondern nur im Body, der aber nicht angefaßt werden soll? Man müßte die Suche bis zu den ersten \n\n einschränken.

 

in etwa also so oder?

```
sed '/^$/q;/X-Header-1/{s/X-Header-1/Y-Header-1/;:x;n;b x}' input.txt
```

----------

## slick

 *Think4UrS11 wrote:*   

> 
> 
> ```
> sed '/^$/q;/X-Header-1/{s/X-Header-1/Y-Header-1/;:x;n;b x}' input.txt
> ```
> ...

 

Danke Think4UrS11, soweit sehr gut, aber teste ich das und der X-Header-1 kommt nicht im Header vor, löscht es mir den Body weg. Man könnte einen test mit einem grep vorher machen, aber ich würde es gern am Stück pipen.

Die Variante von firefly geht hier besser, allerdings ersetzt diese auch im Body.

 *firefly wrote:*   

> 
> 
> ```
> sed -e '/X\-Header\-2/{;s/X\-Header\-2/Y\-Header\-2/;:a' '-en;ba' '-e}'
> ```
> ...

 

----------

## think4urs11

also so funktioniert es bei mir

```
sed 's/X-Header-1/Y-Header-1/;:x;n;bx' input.txt
```

----------

## mastacloak

 *Think4UrS11 wrote:*   

> also so funktioniert es bei mir
> 
> ```
> sed 's/X-Header-1/Y-Header-1/;:x;n;bx' input.txt
> ```
> ...

 

Aber nur, wenn "X-Header-1" auch in der ersten Zeile steht.

Alternativ vielleicht auch mal ein awk-Vorschlag:

```
awk '{ if(!n) n=sub(/X\-Header/,"Y-Header"); print } /^$/ { n=1 }' input.txt
```

Ersetzt den ersten X-Header und hört auch auf zu ersetzen, wenn die erste Leerzeile (zwischen Header und Body) durchgelaufen ist.

----------

## schachti

Ich bin mit sed nicht wirklich sattelfest - vielleicht kann mir einer der Kommandozeilengurus mal eben aushelfen:

Ich möchte in einem LaTex-Dokument alle Vorkommen von

Lemma~\ref{label}

ersetzen durch

\hyperref[label]{Lemma~\ref{label}}

Dafür habe ich mir das folgende sed-Kommando zusammengebastelt:

```
sed 's/Lemma~\\ref{\(.\+\)}/\\hyperref[\1]{Lemma~\\ref{\1}}/g'
```

Das scheint nach einigen Tests auch ganz gut zu klappen - da das Dokument aber sehr groß ist und ich nicht alle Ersetzungen zu 100% kontrollieren kann wüßte ich gerne, ob Ihr in der sed-Zeile irgendwelchen offensichtlichen Fehler seht?

----------

## mv

 *schachti wrote:*   

> Lemma~\ref{label}
> 
> ersetzen durch
> 
> \hyperref[label]{Lemma~\ref{label}}

 

Das klingt für mich nicht so, als ob man das nur durch sed lösen will: Ich würde "Lemma~\ref" ersetzen durch "\thmref{Lemma}" und ein 

```
\newcommand{\thmref}[2]{\hyperref[#2]{#1~\ref{#2}}}
```

am Anfang einfügen.

----------

## schachti

Das ist ein guter Tipp, vielen Dank!

----------

## 3PO

Wie überflüssige Leerzeichen entfernen?

Hallo Zusammen,

ich habe folgendes Problem:

Ich lese mittels wget ein Webinterface einer Software aus und speichere das ganze dann in eine Text Datei.

Allerdings sind in diesem Textfile nun sehr viele unnötige Leerzeichen.

So nun die Frage:

Gibt es eine Möglichkeit, z.B. mit sed, die Datei zu durchsuchen und alle unnötigen Leerzeichen entfernen zu lassen?

Also im Prinzip so:

Suche im Text nach Leerzeichen, - wenn an ein einer Stelle mehr als ein Leerzeichen hintereinander sind, dann lösche alle Leerzeichen bis auf eines.

Geht das mit sed und falls ja, wie?

----------

## manuels

Klar, das geht so:

```
sed 's/ \ */ /g'
```

EDIT: den Backslash brauch man nicht unbedingt.

Und das hier würde ich gerne auf dein Post anwenden:

```
sed 's/\n\n/\n/g'
```

----------

## 3PO

Thx @ manuels,

funktioniert 100%ig.   :Smile: 

----------

## Evildad

 *manuels wrote:*   

> Und das hier würde ich gerne auf dein Post anwenden:
> 
> ```
> sed 's/\n\n/\n/g'
> ```
> ...

 

Gab sogar nen echten Lacher von mir  :Smile: 

----------

## schachti

Hat jemand einen Tipp, wie man mit sed unmittelbar aufeinander folgende doppelte Wörter finden kann (wie zum Beispiel in "hier kommt kommt doppelt vor")? Mir ist aufgefallen, dass ich beim Schreiben ab und zu mal ein Wort zwei Mal hintereinander schreibe und mir diese Fehler beim Korrekturlesen manchmal nicht auffallen...

----------

## schachti

Auch wenn es nichts mit sed zu tun hat - falls jemand vor dem gleichen Problem steht: Mir hat das folgende Perl-Skript geholfen:

http://www.oreilly.de/catalog/regexger/chapter/kap-2l.html.

----------

## pumpkin105

Hallo,

ich durchsuche gerade eine Liste mit regulären Ausdrücken. Meine Zeilen sehen so aus:

```
<font color="#800000">Nachname, Vorname</font>
```

Mein html-Dokument besteht natürlich noch aus mehr Sachen, nur habe ich bisher mir alles so ausgeben lassen, dass ich nur die Zeilen bekomme, wo die Sachen drinne stehen, die ich benötige. Ich würde nun gerne mir mit einem weiteren grep-Befehl alle Nachnamen ausgeben lassen, dh. alles, was zwischen einem > und dem Komma in der Mitte steht. Wie ich Sachen finde, die mit > anfangen und mit , aufhören weiß ich, aber werden dann immer auch die jeweiligen Begrenzungszeichen ausgeben.

Wie muss der Befehl aussehen, dass ich keine Begrenzung bekomme?

Danke für Hilfe

----------

## Evildad

Unschön aber tut bei mir  :Smile: 

```
cat testdatei | awk -F ">" '{print $2}' | awk -F "," '{print $1}'
```

----------

## l3u

```
sed 's/.*>\(.*\),.*/\1/'
```

awk muß man abgesehen davon die Daten nicht per cat über STDIN schicken, da kann man auch eine Datei als Argument abgeben, womit schon ein Befehl und eine Pipe wegfällt ;-)

----------

## pumpkin105

Super, das hat geklappt, jetzt fehlt nur noch eine Sache:

In dem html-Dokument, dass ich durchsuche, will ich jetzt noch Straßennamen raussuchen, die kommen immer in folgender Form vor:

```
12345 Stadt - Musterweg 17<br></td>
```

Es steht also nach dem Straßennamen + Hausnummer immer ein <br></td>

Ich habe es bisher so gemacht:

```
egrep -i -o -e '[A-Za-zßäöü][A-Za-zßöäü\ ]+ [0-9]+'
```

Mir werde fast alle Straßen ausgegeben. 

Bei manchen steht nur 'e 46', dh. alles nach dem ß wird ausgegeben, davor nichts, mit anderen Umlauten habe ich das gleiche Problem.

Andere Straßen stehen dort mit Str. am Ende, ich müsste also den Punkt einfügen. Wenn ich ihn in den zweiten Block mittels \. hinzufüge, bekomme ich aber keine Ausgabe. Außerdem beinhalten manche Straßennamen Namen wie Julius-Caesar-Str., wenn ich auch anch dem Bindestrich suche, werde ich das Problem bekommen ,dass ich den Bindestrich mit bekomme, der vor dem Straßennamen als Abgrenzung zur Stadt steht.

Wie kann ich den Ausdruck so ändern, dass ich das finde, was ich suche?

Danke

----------

## think4urs11

awk hatten wir schon, sed auch also machen wir den Rest doch einfach mal mit cut  :Wink: 

```
echo "12345 Stadt - Julius-Caesar-Allee 17 c<br></td>" | cut -d" " -f4- | cut -d\< -f1
```

----------

## Finswimmer

 *Think4UrS11 wrote:*   

> awk hatten wir schon, sed auch also machen wir den Rest doch einfach mal mit cut 
> 
> ```
> echo "12345 Stadt - Julius-Caesar-Allee 17 c<br></td>" | cut -d" " -f4- | cut -d\< -f1
> ```
> ...

 

Was machst du mit der Stadt "Bad Kreuznach"?

----------

## think4urs11

 *Finswimmer wrote:*   

> Was machst du mit der Stadt "Bad Kreuznach"?

 

Hrmm ok das ist ein Argument; dann eben doch sed

```
echo "12345 New York City - Foobar an der Berg-Wießn 17 c<br></td>" | sed 's/^\([0-9]*\) \(.*\) - \([a-zA-ZßäöüÄÖÜ0-9 -]*\)<.*/\3 - \1, \2/'

Foobar an der Berg-Wießn 17 c - 12345, New York City
```

bzw. nur die Straße:

```
echo "12345 New York City - Foobar an der Berg-Wießn 17 c<br></td>" | sed 's/.* - \([a-zA-ZßäöüÄÖÜ0-9 -]*\)<.*/\1/'

Foobar an der Berg-Wießn 17 c
```

----------

## pumpkin105

Hm, also mein Befehl sieht jetzt so aus:

```
cat plz01.txt | grep -i -e '<br></td>' | sed 's/^\([0-9]*\) \(.*\) - \([a-zA-ZßäöüÄÖÜ0-9 -]*\)<.*/\3 - \1, \2/'
```

Und die Zeilen die mir ausgegeben werden sehen immer noch beispielsweise so aus:

```
                     Ev.Fachklinik Sonnenhöhe<br>                                          08645 Bad Elster - Georg-Leißner-Staße 1-4<br></td>
```

 :Confused: 

----------

## Jean-Paul

Ich habe eine Datei in der Wörter, mit folgendem Muster, stehen:

 *Quote:*   

> aaa bbbb cc www-aaa dddd ee+aaa_x eeeee

 

Ich möchte "aaa" direkt in der Datei löschen.

Das mache ich so:   *Quote:*   

> sed -i -e "s/aaa//g;/^$/d" datei.txt

 

Als Ergebnis erhalte ich jetzt aber

 *Quote:*   

> bbb cc www- dddd ee+_x eeeee

 

Wie bringe ich sed bei, nur das Wort "aaa" zu entfernen und die anderen Wörter, in denen "aaa" vorkommt, in Ruhe zu lassen ?

EDIT: oh, ging doch einfacher als ich dachte.  *Quote:*   

> sed -e "s/^[*]*aaa//g;/^$/d" 

 

Jean-Paul

----------

## mv

 *Jean-Paul wrote:*   

> Wie bringe ich sed bei, nur das Wort "aaa" zu entfernen und die anderen Wörter, in denen "aaa" vorkommt, in Ruhe zu lassen?

 

Die Frage ist mehr als unklar: Inwiefern unterscheidet sich das "aaa", das Du entfernen willst von den anderen? Dadurch, dass es das erste ist? Falls dies der Fall ist, lass doch das "g" (für "global") weg: In dem Fall wird nur der erste Treffer ersetzt...

----------

## Jean-Paul

Nein, es gibt keine Reihenfolge, das "aaa" kann irgendwo stehen.

Ich habe mich zu früh gefreut, meine Lösung funktioniert nicht generell. Will ich "www.aaa" löschen, tut sed nichts.

Jean-Paul

----------

## ScytheMan

Ich krame mal den Thread hervor, um hoffentlich mein Problem zu lösen.

Ich habe eine Musiksammlung in Amarok eingelesen, jedoch fehlen genau 11 Stücke, wenn ich mit der Dateiübersicht (also rechtsklick auf den Musikordner) abgleiche.

Ich habe meine Musik folgendermaßen strukturiert: /Musik/Album/Lied.mp3 bei Alben mit mehreren Discs /Musik/Album/CD 1/Lied.mp3

Ich habe Amarok in Verdacht, dass er mir genau 1 Album/1 CD nicht erkennt.

Jetzt zur Aufgabe:

Ich möchte alle Unterordner mit genau 11 Dateien drin ausfindig machen.

Danke schonmal für eure Tipps!

----------

## Finswimmer

Die Frage ist, wie sieht die Liste aus, mit der du die Dateien vergleichen willst?

Am einfachsten wäre es, wenn du nur die Dateinamen vergleichst. Bleiben welche übrig, kannst du den Pfad dazu suchen.

----------

## ScytheMan

vergleichen wäre auch ne idee.

aber das scheint mir recht kompliziert machbar müsste da höchstens auf die amarok musik datenbank irgendwie zugreifen.

ich hatte gehofft beim aussortieren nach dem 11 dateien kriterium das händisch machen zu können.

----------

## 3PO

Hallo zusammen,

```
sed 's/ABC/123/g' test.txt
```

ersetzt alle "ABC" durch "123" in der Datei test.txt.

Aber wie mache ich das, wenn ich "ABC" durch "123" nur in den Zeilen ersetzen will, die mit "XYZ" beginnen?

----------

## Finswimmer

$cat 1

ABC

ABC

XYZ ABC 

ABC

[21:39:45]|[tobi@tobi-desktop]|/tmp

$sed -e '/^XYZ.*/s/ABC/123/g' 1

ABC

ABC

XYZ 123 

ABC

----------

## 3PO

THX @ Finswimmer,

```
sed -e '/^XYZ.*/s/ABC/123/g'  test.txt
```

Funktioniert soweit, nur leider habe ich dann die Ausgabe nur auf der Konsole, die "test.txt" bleibt aber unverändert.  :Sad: 

----------

## Max Steel

sed -e '/^XYZ.*/s/ABC/123/g'  test.txt > test.txt

----------

## 3PO

Habe es selbst gefunden.  :Smile: 

So gehts:

```
sed -i -e '/^XYZ.*/s/ABC/123/g'  test.txt
```

----------

## mrsteven

 *Max Steel wrote:*   

> sed -e '/^XYZ.*/s/ABC/123/g'  test.txt > test.txt

 

Das ist gefährlich, weil zuerst die Datei test.txt durch die Shell geöffnet und geleert wird. Erst danach öffnet sed die nun leere Datei:

```
stefan@mrsteven-mobil tmp $ cat << EOF > test.txt

> abcd

> efg

> hijk

> EOF

stefan@mrsteven-mobil tmp $ sed -e 's/abcd/ersetzt/' test.txt 

ersetzt

efg

hijk

stefan@mrsteven-mobil tmp $ sed -e 's/abcd/ersetzt/' test.txt > test.txt

stefan@mrsteven-mobil tmp $ cat test.txt 

stefan@mrsteven-mobil tmp $

```

...uncooles Ergebnis. Allgemein werden immer erst die Ein-/Ausgabeumleitungen ausgewertet (und damit evtl. Dateien geleert), bevor das Programm (in diesem Fall sed) selbst gestartet wird und eine Chance bekommt, an den Dateiinhalt heran zu kommen.

</klugscheiß>

----------

## Max Steel

ah okay. Danke war mir auch nicht bewusst ^^

Dann evtl besser sowass hier:

echo $(sed -e '/^XYZ.*/s/ABC/123/g' test.txt) > text.txt

oder doch lieber -i?

Edith:

HaltSTOPP!!! Ist auch Blödsinn Weil:

```
$ echo "ABC

> ABC

> XYZ ABC

> ABC " > test

$ echo $(sed -e '/^XYZ.*/s/ABC/123/g' test)

ABC ABC XYZ 123 ABC

```

Also -i.

----------

## manuels

Willkommen zurück im "never-ending thread"!

Also, ich möchte in einem Javascript-Programm alle Property-Vorkommen der Variable db finden und durch einen Funktionsaufruf ersetzen.

Also z.B. folgende Ersetzungen:

```
db.foo -> db.myFunc("foo")

db.bar -> db.myFunc("bar")

db.bla -> db.myFunc("bla")
```

Nicht ersetzt werden, sollen Funktionsaufrufe von db, z.B.

```
db.someFunc()

db.anotherFunc("stringargument")

db.yetAnotherFunc({a: 3})
```

Ich krieg es aber schon nicht hin einen sed-Ausdruck zu Unterscheidung von Funktionen und Properties zu basteln.

Wieso klappt z.B. das hier nicht:

```
db\.([a-zA-Z0-9]*\w*[^\)])
```

Um jeden Tipp dankbar!

Manuel

----------

## Knieper

 *manuels wrote:*   

> en sed-Ausdruck zu Unterscheidung von Funktionen und Properties zu basteln.
> 
> Wieso klappt z.B. das hier nicht:
> 
> ```
> ...

 

Wieso sollte es? Du liest 'db.' dann eine beliebige Anzahl alphanumerischer Zeichen, gefolgt von einer beliebigen Anzahl alphanumerischer Zeichen und dann ein Zeichen, das kein ')' ist.

Die negierte Zeichenklasse am Ende funktioniert nicht, was Du meinst ist ein negativer Lookahead, den es in sed nicht gibt (dafür in PCRE, Perl, Python...). Dein Problem würde ich momentan so formulieren: lies 'db.' merke Dir die alphanumerischen Zeichen dahinter '(\w+)', wenn danach kein alphanumerisches Zeichen oder eine Klammer kommt.

```

>echo 'db.bar db.LaEnGER; db.foo("test") db.a' |  perl -pe 's/db\.(\w+)(?![(\w])/db.myFunc("\1")/g'

db.myFunc("bar") db.myFunc("LaEnGER"); db.foo("test") db.myFunc("a")
```

In sed müsstest Du Dir behelfen und alle möglichen Zeichen hinter den Variablen kennen, zB. ' ', ';' oder Zeilenende, diese erkennen und dann wieder anfügen:

```

echo 'db.bar db.LaEnGER; db.foo("test") db.a' | sed -r 's/db\.(\w+)([ ;\n]|$)/db.myFunc("\1")\2/g'

db.myFunc("bar") db.myFunc("LaEnGER"); db.foo("test") db.myFunc("a")
```

----------

## Necoro

 *manuels wrote:*   

> 
> 
> ```
> db\.([a-zA-Z0-9]*\w*[^\)])
> ```
> ...

 

Also wenn du Properties matchen willst, sollte das wohl eher

```
db\.\([-_a-zA-Z0-9]\+\)\( |$\)
```

Da sed leider keine "Negative Lookaheads" unterstützt, hab ich jetzt Property als "zusammenhängenden String aus -_a-zA-Z0-9, auf den ein Leerzeichen oder ein Zeilenende folgt" definiert. Evtl sollte man auch noch das "=" oder so aufnehmen. Außerdem ist wichtig, dass sed gruppierende Klammern als "\(\)" erwartet -- "()" würde die Zeichen Klammer-Auf Klammer-Zu matchen. (Außer du nimmst das "-r" was Knieper gerade oben benutzt hat ^^)

----------

## 3PO

Nochmal ne Frage zu sed...

Mit  "sed 's/^/foo_/'" kann ich am Anfang von jeder Zeile ein "foo_" einfügen.

Aber wie gehe ich vor, wenn ich "foo_" am Anfang aller Zeilen einfügen will, ausser(!) bei Zeilen, die z.B. mit einem Doppelpunkt beginnen?

----------

## mv

 *3PO wrote:*   

> Aber wie gehe ich vor, wenn ich "foo_" am Anfang aller Zeilen einfügen will, ausser(!) bei Zeilen, die z.B. mit einem Doppelpunkt beginnen?

 

```
sed -e '/^:/!{s/^/foo_/}'
```

----------

## 3PO

1000 THX @ mv.  :Smile: 

----------

## 3PO

 *mv wrote:*   

>  *3PO wrote:*   Aber wie gehe ich vor, wenn ich "foo_" am Anfang aller Zeilen einfügen will, ausser(!) bei Zeilen, die z.B. mit einem Doppelpunkt beginnen? 
> 
> ```
> sed -e '/^:/!{s/^/foo_/}'
> ```
> ...

 

Nur der Vollständigkeit halber.

Wie wäre denn der sed Befehl, wenn ich "foo_" wieder entfernen wollte?

So?

```
 sed 's/foo_ *//'
```

----------

## Knieper

```
's/^foo_//'
```

----------

## Max Steel

Mal eben eine Frage, und zwar habe ich die Ausgabe von grep samt filename.

Und möchte für die Weiterverarbeitung nur die Filenamen (ob mehrmals vorhanden oder nicht) weiterverwenden.

Wie lässt sich das am einfachsten machen (alle Filenamen haben die gleiche Struktur: f[0-9]*.txt

bsp:

f21292056.txt:From: <abc@abc.de>

Ab dem Filenamen ist der zweite Teil Variabel.

----------

## firefly

 *Max Steel wrote:*   

> Mal eben eine Frage, und zwar habe ich die Ausgabe von grep samt filename.
> 
> Und möchte für die Weiterverarbeitung nur die Filenamen (ob mehrmals vorhanden oder nicht) weiterverwenden.
> 
> Wie lässt sich das am einfachsten machen (alle Filenamen haben die gleiche Struktur: f[0-9]*.txt
> ...

 

ist der doppelpunkt nach dem dateinamen auch immer vorhanden? Wenn ja könnte man auch was mit "cut" machen.

folgendes ungetestet bin gerade nicht an einem rechner mit ner unix shell

```
echo "f21292056.txt:From: <abc@abc.de>" | cut -d':' -f0
```

----------

## Max Steel

 *firefly wrote:*   

> ist der doppelpunkt nach dem dateinamen auch immer vorhanden? Wenn ja könnte man auch was mit "cut" machen.
> 
> folgendes ungetestet bin gerade nicht an einem rechner mit ner unix shell
> 
> ```
> ...

 

Jupp. der Doppelpunkt ist immer vorhanden (wie schon gesagt, ein Output von grep mit dateinamen).

Super so funktioniert das (ich weiß nicht ob das am Windows-unxutils-cut liegt aber ich musste -f1 auswählen, vll einfach ein Kompatibiltätsquatsch seitens Windows.)

----------

## firefly

 *Max Steel wrote:*   

> Super so funktioniert das (ich weiß nicht ob das am Windows-unxutils-cut liegt aber ich musste -f1 auswählen, vll einfach ein Kompatibiltätsquatsch seitens Windows.)

 

Ne das mit -f1 kann schon passen, wie schon gesagt die beispielzeile hatte ich einfach aus dem kopf geschrieben, da ich aktuell keinen zugriff auf eine unix/linux shell habe.

----------

## Max Steel

Kann ich dann direkt wenn ich zuhause bin nachschaun (bin noch auf Arbeit)

----------

## slick

Ich bräuchte auch mal etwas Hilfe. Ich habe einen (eigentlich mehrzeiligen) Text in dem an irgendeiner Stelle eine bestimmte ID (in einem bestimmten Format) befindet. (Ein die ID umfliessender Text ist nicht zwangsläufig, der "Text" kann auch nur die ID selbst sein) Diese ID möchte ich gern extrahieren.  D.h. Text rein, ID raus. Die ID besteht aus Komponenten mit fixer Länge, jedoch gibt es auch Abweichler. Eigentlich brauche ich somit zwei Code-Schnipsel. Einer der die ID exakt gemäß der fixen Längen extrahiert (und andere ignoriert) und eine weichere Version die auch IDs mit ungleich langen Komponenten findet, sofern das Muster stimmt.

Die ID setzt sich wie folgt zusammen (case-insensitiv)

YYMMDD-X-YYYYY-ZZZ

Dabei gilt:

YYMMDD - 6 stellige Datumsangabe [0-9]

X - einstelliger Buchstabe [A-Z]

YYYYY - 5 stelliger Wert [A-Z,0-9]

ZZZ - 3 stellige Zahl [0-9]

Teilweise ist die ID durch Leerzeichen vom Text getrennt, stellenweise aber auch um weitere Zeichen erweitert die ich nicht mit extrahiere möchte. z.b: Buchstaben davor oder dahinter (a, b). z.B. aYYMMDD-X-YYYYY-ZZZb.

Das waren die Angaben für die "strenge" Prüfung. Für die weichere Variante sehen die Regeln wie folgt aus:

NNNNNN-X-YYYYY-ZZZ

NNNNNN - n stelliger Zahlenwert [0-9], wobei sich die Länge durch die "umschliessenden" nicht-numerischen Zeichen ergibt

X - n stelliger Buchstabenwert [A-Z], wobei sich die Länge durch das umschliessenden Zeichen "-" ergibt

YYYYY - n stelliger Wert [A-Z,0-9], wobei sich die Länge durch das umschliessenden Zeichen "-" ergibt

ZZZ - n stellige Zahl [0-9], wobei sich die Länge durch die "umschliessenden" nicht-numerischen Zeichen ergibt

Auch hier gilt wieder, die ID könnte um anderen Zeichen ergänzt sein, die ich nicht möchte (a,b) : aNNNNNN-X-YYYYY-ZZZb.

----------

## 3PO

Hallo Zusammen,

ich stehe mal wieder auf dem Schlauch, was sed angeht....

Das,

```
sed -e 's/;.*$//'
```

löscht ja das ";" und alles nachfolgende in der Zeile.

Wie gehe ich aber vor, wenn ich folgendes machen will:

Lösche das ";" und alles nachfolgende in der Zeile und füge dafür ".abc" ein.

----------

## mrsteven

```
sed -e 's/;.*$/.abc/'
```

Oder habe ich dein Problem falsch verstanden?

----------

## 3PO

Ja, das wars, 1000 THX.

----------

## 3PO

Hallo Zusammen,

kann sed eigentlich auch "von hinten" rechnen?

Ich bräuchte von jeder Zeile nur das siebte und das achte Zeichen, allerdings von hinten her gerechnet.

Geht so etwas mit sed?

----------

## mv

 *3PO wrote:*   

> Ich bräuchte von jeder Zeile nur das siebte und das achte Zeichen, allerdings von hinten her gerechnet.

 

```
-e 's/^.*\(..\)......$/\1/'
```

----------

## 3PO

1000 THX @ mv,

das funktioniert 100%ig, allerdings ist mir die Syntax nicht so ganz klar.   :Very Happy: 

----------

## mv

^: Zeilenanfang:

.*: Gefolgt von irgendwelchen Zeichen (beliebig vielen).

\(: Das folgende merken wir uns in \1

..: Zwei beliebige Zeichen

\): Ende des Merkens

......: Sechs weitere Zeichen

$: Zeilenende

Danach wird der Treffer durch das Gemerkte ersetzt.

----------

## 3PO

Danke, für die ausführliche Erklärung.  :Smile: 

----------

## 3PO

Hallo Zusammen,

ich habe mal wieder ein Problem, beim Zerlegen von Strings, allerdings weiß ich nicht, ob das über Haupt mit sed geht.

Ich habe ein Script, dass mir folgende Ausgabe liefert:

```
5102=deu@3,5103=mis@3;5106=deu@106

6120=deu@3,6121=mis@3,6123=mul@3;6122=deu@106

102=deu@3,103=mis@3;106=deu@106

120=deu@3,121=mis@3,122=mul@3;125=deu@106
```

Aussehen sollte das Ganze aber so:

```
5102,5103,5106

6120,6123,6122

102,103,106

120,121,122,125
```

Also nur die Zahlen, vor den "=", getrennt mit Komata.

Hat Jemand eine Idee, wie man das lösen kann?

----------

## mv

```
-e 's/\=[^,;]*\([,;]\|$\)/\1/g' -e 's/;/,/g'
```

----------

## 3PO

1000 THX @ mv!

Funktioniert, wie immer 100%ig.  :Smile: 

----------

## schitthoch3

Hallo zusammen

Mein Kabelprovider sendet leider bewusst falsche DVB-C Senderdaten. Siehe dazu mehr hier. Ich habe nun eine channels.conf für VDR in der alle Sender zweimal (an zwei unterschiedlichen Zeilen) gelistet sind. Das ist die Ausgangslage. Ein Beispiel:

 *Auszug aus der channels.conf wrote:*   

> 
> 
> [...]
> 
> ZDF HD;upc:514000:M256:C:6900:80=27:81=deu@3,82=mis@3,83=mul@3;91=deu@106:110:0:9007:1:78:0
> ...

 

Ich möchte nun von oben herab ausgehend für alle Kanäle nach dem Namen suchen (erster String vor dem Semikolon) und vom ersten Eintrag mit gleichem Namen den zweitletzten String (7 :Cool:  durch den String des zweiten Eintrages mit gleichem Namen ersetzen (83). Danach soll der zweite Eintrag gleichen Namens gelöscht werden. Sobald es keinen Zweiteintrag mit gleichem Sendernamen mehr gibt, soll das Script enden.

Am Schluss soll die channels.conf jeden Kanal nur einmal enthalten (die unteren Zeilen-Einträge gelöscht) mit "gemergten" Inhalten also z.B.

ZDF HD;upc:514000:M256:C:6900:80=27:81=deu@3,82=mis@3,83=mul@3;91=deu@106:110:0:9007:1:83:0

Anmerkung: Die Zeilen Enden immer mit :0, dass heisst man kann in der oberen Zeile des Namenpaares alles ab dem zweitletzten : ersetzen.

Ich hoffe ich konnte dies jetzt sinnvoll erklären. Ansonsten bitte nachfragen. 

Hat da jemand eine Lösung?

----------

## 3PO

Hallo Zusammen,

ich stehe mal wieder auf dem Schlauch.  :Smile: 

Ich habe ein Script, das mir eine Datei nach folgendem Schema füllt:

```
foo="1"

bar="abc"

xyz="0,2"
```

Soweit, so gut. Leider aber kommt es vor, dass auch solche Einträge erzeugt werden:

```
foo="1" aa"er

bar="abc"  23
```

Meine Frage ist nun, wie kann ich mit sed, in jeder Zeile, alles löschen, was nach dem zweiten " kommt?

----------

## firefly

 *test.txt wrote:*   

> foo="1"
> 
> bar="abc"
> 
> xyz="0,2"
> ...

 

```
 sed -e 's/\([a\-z]*="[^"]*"\).*$/\1/g' < test.txt
```

 *Quote:*   

> foo="1"
> 
> bar="abc"
> 
> xyz="0,2"
> ...

 

Es wird der gewünschte text in eine gruppe selektiert und die ganze zeile wird dann mit dem content der gruppe ersetzt

----------

## firefly

 *3PO wrote:*   

> 
> 
> Soweit, so gut. Leider aber kommt es vor, dass auch solche Einträge erzeugt werden:
> 
> ```
> ...

 

Wäre es nicht besser das script zu fixen?

----------

## 3PO

 *firefly wrote:*   

> 
> 
> Wäre es nicht besser das script zu fixen?

 

Ist doch gefixt, mit:

```
sed -e 's/\([a\-z]*="[^"]*"\).*$/\1/g' < test.txt
```

 :Laughing:   :Laughing:   :Laughing: 

BTW: 1000 THX für die schnelle Hilfe!

----------

