sed - Zeichenkette korrekt suchen

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
uname
Beiträge: 12405
Registriert: 03.06.2008 09:33:02

sed - Zeichenkette korrekt suchen

Beitrag von uname » 19.06.2013 11:13:44

Ich versuche gerade eine Zeichenkette zu finden, die zwischen zwei anderen Zeichenketten steht. Das Beispiel habe ich im Internet gefunden. Mein eigentliches Problem wäre etwas komplizierter. Ist aber wohl ein Verständnisproblem von "sed".

Code: Alles auswählen

echo "Dies ist ein ganz einfacher Test"  | sed -e 's/^.*ein\(.*\)einfacher.*$/\1/'                                        
 ganz 
Wenn nun aber die erste oder zweite Zeichenkette gar nicht existiert (hier Wort "einfacher"), dann hätte ich keinen Treffer haben wollen, aber ich erhalte die ganze Zeile.

Code: Alles auswählen

echo "Dies ist ein ganz schwerer Test"  | sed -e 's/^.*ein\(.*\)einfacher.*$/\1/'                                         
Dies ist ein ganz schwerer Test
Wo liegt mein Denkfehler? Sollte doch nicht so schwer sein, oder?

Nachtrag:
Eigentlich klar. Es gibt keinen Treffer und keine Substitution. Wie substituiere ich denn nach "" wenn es keinen Treffer gibt?

syssi
Beiträge: 2951
Registriert: 24.12.2010 16:50:59
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: Rheinland

Re: sed - Zeichenkette korrekt suchen

Beitrag von syssi » 19.06.2013 11:19:02

Wie waers mit:

Code: Alles auswählen

echo "Dies ist ein ganz schwerer Test"  | sed -ne 's/^.*ein\(.*\)einfacher.*$/\1/'    
Es gibt aber auch noch diesen Weg:

Code: Alles auswählen

sed -e /patt/!d;s//repl/
vgl. http://stackoverflow.com/a/6011704

uname
Beiträge: 12405
Registriert: 03.06.2008 09:33:02

Re: sed - Zeichenkette korrekt suchen

Beitrag von uname » 19.06.2013 11:46:07

Danke für die Lösung. Es sollte darum gehen, dass ich in HTML-Code Einträge der Form

Code: Alles auswählen

paket.deb
finde und dann ausgebe. Gefunden wird der Treffer in Anführungszeichen.

Code: Alles auswählen

1. Zeile:
<tr><td valign="top"><img src="/icons/unknown.gif" alt="[   ]"></td><td><a href="cb-exit_0.01_all.deb">cb-exit_0.01_all.deb</a></td><td a
lign="right">16-Apr-2012 14:48  </td><td align="right">2.4K</td><td>&nbsp;</td></tr>
2. Zeile:
<tr><td valign="top"><img src="/icons/unknown.gif" alt="[   ]"></td><td><a href="arandr_0.1.6-1crunchbang1.dsc">arandr_0.1.6-1crunchbang1
.dsc</a></td><td align="right">25-Jul-2012 08:37  </td><td align="right">780 </td><td>&nbsp;</td></tr>
3. Zeile:
<tr><td valign="top"><img src="/icons/compressed.gif" alt="[   ]"></td><td><a href="xfce4-volumed_0.1.13-3crunchbang.debian.tar.gz">x
fce4-volumed_0.1.13-3crunchbang.debian.tar.gz</a></td><td align="right">07-Oct-2012 17:23  </td><td align="right">2.5K</td><td>&nbsp;
</td></tr>
Nun gibt es aber noch ein Problem mit der letzten Zeile

Code: Alles auswählen

cat m.htm | sed -e '/^.*\(.\)\(.*\.deb\)\1.*$/!d;s//\2/'     
cb-exit_0.01_all.deb
an.tar.gz">xfce4-volumed_0.1.13-3crunchbang.deb
Wo muss ich denn nun noch sagen, dass ich vor meinem auszugebenden regulären Ausdruck die Anführungszeichen oder mindestens nach dem "deb" einen Nicht-Buchstaben erwarte? Wahrscheinlich gibt es auch eine einfachere grep-Lösung, oder?
Zuletzt geändert von uname am 19.06.2013 12:41:23, insgesamt 1-mal geändert.

syssi
Beiträge: 2951
Registriert: 24.12.2010 16:50:59
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: Rheinland

Re: sed - Zeichenkette korrekt suchen

Beitrag von syssi » 19.06.2013 12:07:54

Spricht etwas dagegen das HTML-Markup zu beachten?

Code: Alles auswählen

$ cat m.html | sed -e '/^.*href="\([^"]*\)".*$/!d;s//\1/' 
cb-exit_0.01_all.deb
arandr_0.1.6-1crunchbang1.dsc
xfce4-volumed_0.1.13-3crunchbang.debian.tar.gz
bzw.

Code: Alles auswählen

$ cat m.txt| sed -e '/^.*href="\([^"]*\.deb\)".*$/!d;s//\1/' 
cb-exit_0.01_all.deb
wenn du dich nur fuer Pakete interessierst.

uname
Beiträge: 12405
Registriert: 03.06.2008 09:33:02

Re: sed - Zeichenkette korrekt suchen

Beitrag von uname » 19.06.2013 12:40:53

Die letzte Lösung ist gut. Vor allem, dass man nach etwas sucht was keine Anführungszeichen [^"] enthält, den Begriff .deb an Ende enthält und worauf dann die schließenden Anführungszeichen folgen ist natürlich genial.
Vielen Dank für die Lösungen.

Benutzeravatar
Meillo
Moderator
Beiträge: 9239
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: sed - Zeichenkette korrekt suchen

Beitrag von Meillo » 25.06.2013 13:20:29

syssi hat geschrieben:Wie waers mit:

Code: Alles auswählen

echo "Dies ist ein ganz schwerer Test"  | sed -ne 's/^.*ein\(.*\)einfacher.*$/\1/'    
Es gibt aber auch noch diesen Weg:

Code: Alles auswählen

sed -e /patt/!d;s//repl/
vgl. http://stackoverflow.com/a/6011704
Das stimmt schon, ist aber unnoetig kompliziert. Der Ansatz zuvor war schon gut, nur dass er den Fall einer Zeile ohne Treffer nicht abgedeckt hat:
uname hat geschrieben:

Code: Alles auswählen

echo "Dies ist ein ganz einfacher Test"  | sed -e 's/^.*ein\(.*\)einfacher.*$/\1/'                                        
 ganz 
Wenn nun aber die erste oder zweite Zeichenkette gar nicht existiert (hier Wort "einfacher"), dann hätte ich keinen Treffer haben wollen, aber ich erhalte die ganze Zeile.

Code: Alles auswählen

echo "Dies ist ein ganz schwerer Test"  | sed -e 's/^.*ein\(.*\)einfacher.*$/\1/'                                         
Dies ist ein ganz schwerer Test
Dieses standardmaessige Ausgeben einer Zeile kann man einfach mit `-n' abschalten. Dann muss man allerdings die Zeilen mit Treffer explizit ausgeben. Dafuer haengt man ein `p' an das `s'-Kommando an:

Code: Alles auswählen

sed -n 's/^.*ein\(.*\)einfacher.*$/\1/p'
(btw: `-e' ist unnoetig wenn man nur eine einzelne Anweisung hat.)

Und diesen Ansatz nochmals fuer den letzten, HTML-sensitiven Ausdruck angepasst:

Code: Alles auswählen

sed -n 's/^.*href="\([^"]*\.deb\)".*$/\1/p'
Ich denke, das liest sich einfacher, da keine Negation noetig ist.
Use ed once in a while!

uname
Beiträge: 12405
Registriert: 03.06.2008 09:33:02

Re: sed - Zeichenkette korrekt suchen

Beitrag von uname » 25.06.2013 16:08:02

Danke. Werde ich mir genauer anschauen und entsprechend digital merken.

Antworten