string herausfischen mit sed oder awk

dosenfleisch

dosenfleisch

Foren As
hallo,

schreibe schon seit einiger zeit bash-scripte, habe aber bisher sed und awk immer irgendwie umschiffen können. gerade sed erscheint mir bei euren code-schnipseln immer wahnsinnig mächtig, aber auch undurchsichtig.

nun möchte ich nichts weiter tun, als aus einer xml-datei den string zwischen
<title> und </title>
herausfiltern um ihn dann weiter zu verarbeiten.
dieser "title-tag" kann in dieser datei (atomfeed) häufiger vorkommen und ich möchte jeweils den inhalt .

Code:
sed -n /<title>/,</title>/pg datei 
#oder
sed -n /<title>/,<\/title>/pg datei
sollte es doch eigentlich schaffen. funktioniert aber leider nicht.
die xml-datei läuft übrigens über zwei zeilen.

worin besteht bei meinem code der fehler?
 
Zuletzt bearbeitet:
quick and dirty
Code:
cat input.xml | grep title | sed 's/<title>/;/' | sed 's/<\/title>/;/' | cut -d ";" -f 2
So würde ich das auf die Schnelle machen. Sicherlich nicht die eleganteste Lösung aber läuft :D
Der Fehler bei deinem Ansatz ist, dass du versuchst den String "<title>" durch ",</title>" zu ersetzen.
Hier noch bissl was zu sed.
http://www.fibel.org/linux/lfo-0.6.0/node170.html
 
danke L0s3r.

und wie komme ich jetzt an alle in den title-tags enthaltene strings?
<title> 1 </title>
<title>2 </title>
<title> 3 </title>
alle in einer zeile mit anderen tags dzwischen.
sicher mit einer schleife, aber ich weiß nicht wo diese ansetzt.
 
Zur erklärung:
cat lädt die Datei, grep filtert alle zeilen raus die "title" enthalten, die beiden sed's ersetzen jeweils "<title>" und "</title>" durch ";" und cut gibt aus, was zwischen beiden ";" steht.
Also beim Beispiel
Code:
<title> 1 </title>
<title>2 </title>
<title> 3 </title>
wird dann
Code:
1
2
3
ausgegeben.

Edit: Der Teil mit dem Ersetzen von <title> zu ; ist leider notwendig weil cut nur ein einzelnes Zeichen als Trenner akzeptiert deswegen ist es wie gesagt nicht die eleganteste Lösung.
 
danke nochmal für die erklärung. bis auf den sed-teil war mir das schon verständlich, nun begreif ich aber auch den rest. :)

aber:
Code:
while `cat testdatei`; do grep title | sed 's/<title>/;/' | sed 's/<\/title>/;/' | cut -d ";" -f 2 ; done
auf diese testdatei angewandt:
Code:
<title> 1 </title><title> 2 </title><title> 3 </title>
führt zu
Code:
...: line 5: <title>: command not found
 
Ja da haut was mit der while-Schleife nicht hin und bei dieser Konstellation in der Testdatei klappt auch der Rest nicht mehr weil dann nur der erste Titel ausgegeben wird und das ist ja nicht Sinn der Übung. Wie sieht denn die Originaldatei nun aus?
 
ich muß um entschuldigung bitten. ich habe da verschiedenes in einen topf gehauen.
also:

Code:
cat testdatei | grep title | sed 's/<title>/;/' | sed 's/<\/title>/;/' | cut -d ";" -f 2
auf diese testdatei angewandt:
Code:
<title> 1 </title><title> 2 </title><title> 3 </title>
führt zu:
Code:
1

also soweit alles okay, bis auf die tatsache, daß ich nur den ersten title erhalte.


das ist der atomfeed von google:

Code:
<?xml version="1.0" encoding="UTF-8"?>
<feed version="0.3" xmlns="http://purl.org/atom/ns#"><title>Gmail - Inbox for blabla@gmail.com</title><tagline>New messages in your Gmail Inbox</tagline><fullcount>2</fullcount><link rel="alternate" href="http://mail.google.com/mail" type="text/html"/><modified>2007-12-16T16:38:30Z</modified><entry><title>Ihre Teilnahme am ... .</title><summary>weitere erklaerungen &amp;hellip;</summary><link rel="alternate" href="http://mail.google.com/mail?account_id=klopapier%40gmail.com&amp;message_id=111f&amp;view=conv&amp;extsrc=atom" type="text/html"/><modified>2007-12-14T16:46:15Z</modified><issued>2007-12-14T16:46:15Z</issued><id>tag:gmail.google.com,2004:36656</id><author><name>flup flop.</name><email>news@news.flammplupp.com</email></author></entry><entry><title>meintitel</title><summary>hier die summery &amp;hellip;</summary><link rel="alternate" href="http://mail.google.com/mail?account_id=blabla%40gmail.com&amp;message_id=b0c3853&amp;view=conv&amp;extsrc=atom" type="text/html"/><modified>2007-11-20T17:00:12Z</modified><issued>2007-11-20T17:00:12Z</issued><id>tag:gmail.google.com,2004:1253655</id><author><name>Icke </name><email>dingdong@dada.info</email></author></entry></feed>

da sind also zwei emails drin enthalten.
beide titel will ich haben, vllt später auch mehr, nur mir fehlt die technik.
 
Es wird immer schmutziger :D
Code:
cat test | grep title | sed -e 's/<title>/+/g' -e 's/<\/title>/+/g' | cut -d "+" -f "2,4,6,8"
Den Trenner von ";" auf "+" umgestellt weil ";" auch an anderen Stellen auftaucht. Mit der Variante müsstest du die Zahlenfolge 2,4,6,8 weiterführen je nachdem wie viele Titel rausgefischt werden sollen. Vllt hat ja jemand doch noch was eleganteres ^^
 
@L0s3r
das funktioniert jetzt. ich muß nur noch die title voneinander trennen, aber das wiederum sollte ich mit cut oder sed allein hinkriegen. danke!

@P17
wenn die tags alle weg sind, finde ich die titel gar nicht mehr, oder habe ich da was übersehen?
 
Also wenn ich das hier durchlaufen lasse sind die Titel durch ein "+" getrennt.
 
genau, sieht doch aber scheiße aus ;)
ich hab's jetzt so:
Code:
mail=$(cat 'atomfeed' | grep title | sed -e 's/<title>/+/g' -e 's/<\/title>/+/g' | cut -d "+" -f "4,6,8,10,12")
mail=$(sed 's/+/\n/' <<< "$mail")
echo "$mail"
ich danke dir!
 
Code:
sed 's/+/\n/[B]g[/B]'
kannst du noch an die Pipe anhängen
Code:
cat test | grep title | sed -e 's/<title>/+/g' -e 's/<\/title>/+/g' | cut -d "+" -f "2,4,6,8,10,12" | sed 's/+/\n/g'
 
ist mir auch grad in der wanne eingefallen :)

edit:

daraus ist jetzt ein schöner (kleiner) gmail-checker geworden.
Code:
wget -O atomfeed https://mail.google.com/gmail/feed/atom --http-user=mymail@gmail.com --http-password=mypass
mail=$(cat 'atomfeed' | grep name | sed -e 's/<name>/+/g' -e 's/<\/name>/+/g' | cut -d "+" -f "2,4,6,8,10,12"| sed 's/+/\n/g')
echo "$mail" | osd_cat -A right -p bottom -f -adobe-helvetica-*-*-*-*-18-*-*-*-*-*-*-* -c red -d 65 & > /dev/null
funzt nur, wenn die osd-tools bzw osd-bin installiert sind und die schrift im system existiert.
 
Zuletzt bearbeitet:
Hallo
Sorry, aber das sieht grauenhaft aus.
UUOC sagt Euch was?

Sowas wie
Code:
cat file|grep "match"|sed ...
ist mindestens einmal meist sogar zweimal sinnfrei.
Code:
grep "match" file
...macht das Gleiche und spart einen Prozess!
sed selbst nimmt auch eine Datei entgegen und kann auch selbst alles was nicht matcht ausfiltern. Damit haben wir schon zwei Prozesse gespart.
Code:
# falsch!
cat file|grep "pattern"|sed ...
# richtig
sed -e /pattern/!d;...' file
Löscht (ignoriert sie bei der Ausgabe) alle Zeilen aus file, die nicht auf pattern matchen.
Genau das tut das sinnlose
Code:
cat file|grep "pattern"| sed...
... auch.

Nur mal so am Rande bemerkt.
Code:
sed -n /<title>/,</title>/pg datei 
#oder
sed -n /<title>/,<\/title>/pg datei
sollte es doch eigentlich schaffen. funktioniert aber leider nicht.
Die Erklärung von L0s3r
Der Fehler bei deinem Ansatz ist, dass du versuchst den String "<title>" durch ",</title>" zu ersetzen.
ist leider total falsch.

Bei dem Versuch wird nix ersetzt, sondern die Addressierung verwendet.
das muss scheitern, da diese zeilenorientiert arbeitet.
genauer bedeutet das:
Code:
sed -n /<title>/,</title>/pg datei

-n nicht ausgeben
/<title>/,</title>/p alle Zeilen beachten die mit Zeile startet welche <title> enthält und solange weiter beachten, bis eine Zeile kommt die </title> enthält. Da ist noch ein Syntaxfehler drin. Du musst den Slash schützen (Escapen).

Eine Ersetzung setzt ein s/find/replace/ vorraus.
y geht auch, arbeitet dann wie tr.
Aber hier ist ein Adressbereichsanfang verwendet, wobei das Ende syntaktisch falsch ist.
Sed versucht also mit Adressbereichen zu arbeiten, und scheitert dann wegen Syntaxfehler.
Das g am Ende ist sinnlos und falsch (Syntaxfehler), was dir sed sicher auch gemeldet hat.

Das nur zur Richtigstellung.

Nix für ungut, aber das musste ich loswerden.
Hier soll ja keine falsche Info stehenbleiben, andere könnten später auch davon profitieren wollen.

Also nicht persönlich nehmen.
Gruß Wolfgang.
 
Nix für ungut, aber das musste ich loswerden.
Hier soll ja keine falsche Info stehenbleiben, andere könnten später auch davon profitieren wollen.

wer es etwas genauer weiß und sich die zeit nimmt, hier und da das fachgefasel ein wenig zu erläutern, ist den neuankömmlingen eine große hilfe!

oft sind es deine postings "hintendran", die aus undurchdringlichen codezeilen etwas machen, was dieses subforum zu einem kleinen wiki werden läßt.
 

Ähnliche Themen

Ausgabe an einen String

CSV Datei mit sed manipulieren/optimieren/ergänzen

Suchen und ersetzen in einer Textdatei

awk: Dateiinhalt/Variableninhalt als Teil einer if-Anweisung

Ersetzen von Text mit Datei-Inhalt

Zurück
Oben