[gelöst] awk: Suchen und nur 2te oder letzte Fundstelle ausgeben

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
Benutzeravatar
detix
Beiträge: 1743
Registriert: 07.02.2007 18:51:28
Wohnort: MK

[gelöst] awk: Suchen und nur 2te oder letzte Fundstelle ausgeben

Beitrag von detix » 10.11.2018 13:14:52

Es geht um das EPG und Sendungstitel eines TV-Senders was im Html Format vorliegt,
hier gekürzt zB (Dateiname: 111):

Code: Alles auswählen

blah
<span class="event">Panda, Gorilla & Co. (271)</span>
blah
<span class="event">Quarks im Ersten</span>
blah
So bekomme ich beide Ausgaben, es sind eigentlich nur zwei und Leerzeichen werden durch Unterstrich ersetzt:

Code: Alles auswählen

awk -F "[<>]" '/class="event"/ { gsub(/ /,"_"); print $3 }' 111
Panda,_Gorilla_&_Co._(271)
Quarks_im_Ersten
so nur die erste Ausgabe:

Code: Alles auswählen

awk -F "[<>]" '/class="event"/ { gsub(/ /,"_"); print $3; exit }' 111
Panda,_Gorilla_&_Co._(271)
Ich hätte aber gern nur die letzte Ausgabe, so gehts:

Code: Alles auswählen

tac 111 | awk -F "[<>]" '/class="event"/ { gsub(/ /,"_"); print $3; exit }'
Quarks_im_Ersten
Aber wie sag ichs awk, ohne useless use of cat tac?
Zuletzt geändert von detix am 10.11.2018 19:06:48, insgesamt 1-mal geändert.
Gruß an alle Debianer, und immer daran denken:
Macht ohne Haftung funktioniert nicht!

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

Re: awk: Suchen und nur 2te oder letzte Fundstelle ausgeben

Beitrag von Meillo » 10.11.2018 13:45:18

Statt dem print kannst du einfach eine Variable setzen (d.h. ueberschreiben), dann steht dort immer der letzte Wert. Die kannst du dann in einem END-Block ausgeben.


Btw: Wenn tac eine Funktion erfuellt, ist es nicht useless. ;-)
Use ed once in a while!

Benutzeravatar
detix
Beiträge: 1743
Registriert: 07.02.2007 18:51:28
Wohnort: MK

Re: awk: Suchen und nur 2te oder letzte Fundstelle ausgeben

Beitrag von detix » 10.11.2018 15:30:26

Wenn ich nur wüßte wie und wo ich diesen END-Block reinschreiben muss...
irgendwie steht dieser, laut meiner Netz_der_Netze Recherche immer vor einer öffnenden geschweiften Klammer, klappt hier nicht (wegen gsub?).
Wie schön wäre eine fertige Befehlszeile dafür...
Da bleib ich doch lieber bei useless use of tac :roll:
Gruß an alle Debianer, und immer daran denken:
Macht ohne Haftung funktioniert nicht!

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

Re: awk: Suchen und nur 2te oder letzte Fundstelle ausgeben

Beitrag von Meillo » 10.11.2018 17:16:51

Willst du es (1) verstehen oder willst du (2) nur einen funktionierenden Code bekommen?

Fuer (1): Awk-Scripte bestehen aus einer Liste von Condition-Action Paaren. Actions sind das was in geschweifte Klammern eingebettet ist (d.h. die Bloecke). Wenn die Action fehlt, wird die Default-Action {print} ausgefuehrt. Conditions, also Bedingungen stehen vor den Action-Bloecken. Sie koennen Logische Ausdruecke sein oder Regexes oder eben ``BEGIN'' (= bevor die erste Zeile eingelesen wird) oder ``END'' (nachdem das Script fertig bearbeitet ist). Wenn die Bedinung fehlt wird als Default-Bedinung True angenommen, d.h. sie trifft fuer jede Zeile zu.

... du solltest es verstehen wollen. Es ist gar nicht schwer. :-)


Fuer (2):

Code: Alles auswählen

awk -F "[<>]" '
/class="event"/ {
	gsub(/ /,"_")
	stored=$3
}

END {
	print stored
}
' 111
Oder als Einzeiler:

Code: Alles auswählen

awk -F "[<>]" '/class="event"/ { gsub(/ /,"_"); stored=$3 } END { print stored }' 111
Use ed once in a while!

Benutzeravatar
detix
Beiträge: 1743
Registriert: 07.02.2007 18:51:28
Wohnort: MK

Re: awk: Suchen und nur 2te oder letzte Fundstelle ausgeben

Beitrag von detix » 10.11.2018 19:04:50

So tief möchte ich in die Programmierung von awk gar nicht einsteigen, dessen Funktionsumfang übersteigt das was ich für mich nutzen möchte bei Weitem...
Im Grunde hast du mir die Antwort schon in deinem ersten Post gegeben, habs nur nicht verstanden, manchmal sieht man halt den Wald vor lauter Bäumen nicht, sprich:
man verbiestert sich in irgendwas und denkt viel zu kompliziert..., und dabei ist die Lösung so einfach, also Variable:

Code: Alles auswählen

x=$(awk -F "[<>]" '/class="event"/ { gsub(/ /,"_"); print $3 }' 111)
meinLieblingsErgebnis=$(echo $x | awk '{ print $2 }')
echo $meinLieblingsErgebnis
Quarks_im_Ersten
Da Leerzeichen schon durch einen Unterstrich ersetzt wurden, entspricht $2 auch dem gewünschten Ergebnis,
$3 ist demnach also die dritte Fundstelle falls vorhanden...

Code: Alles auswählen

awk -F "[<>]" '/class="event"/ { gsub(/ /,"_"); stored=$3 } END { print stored }' 111
funktioniert natürlich genauso, sofern es sich um die letzte Fundstelle handelt...
gelöst, vielen Dank Meillo für diese verbalen Kopfnüsse! :D
Gruß an alle Debianer, und immer daran denken:
Macht ohne Haftung funktioniert nicht!

Huo
Beiträge: 778
Registriert: 26.11.2017 14:03:31
Wohnort: Freiburg

Re: [gelöst] awk: Suchen und nur 2te oder letzte Fundstelle ausgeben

Beitrag von Huo » 10.11.2018 20:08:56

detix hat geschrieben: ↑ zum Beitrag ↑
10.11.2018 19:04:50
..., und dabei ist die Lösung so einfach, also Variable:

Code: Alles auswählen

x=$(awk -F "[<>]" '/class="event"/ { gsub(/ /,"_"); print $3 }' 111)
meinLieblingsErgebnis=$(echo $x | awk '{ print $2 }')
echo $meinLieblingsErgebnis
Quarks_im_Ersten
Da Leerzeichen schon durch einen Unterstrich ersetzt wurden, entspricht $2 auch dem gewünschten Ergebnis,
$3 ist demnach also die dritte Fundstelle falls vorhanden...
Die zweite (analog: dritte, vierte, ..., n-te) Fundstelle ließe sich auch direkt ausgeben, also ohne Umweg über eine zusätzliche Variable:

Code: Alles auswählen

awk -F "[<>]" '/class="event"/ {i++}i==2{  gsub(/ /,"_"); print $3; exit }' 111

Benutzeravatar
detix
Beiträge: 1743
Registriert: 07.02.2007 18:51:28
Wohnort: MK

Re: [gelöst] awk: Suchen und nur 2te oder letzte Fundstelle ausgeben

Beitrag von detix » 10.11.2018 21:10:06

Na, da kommt doch noch etwas Anderes...

Code: Alles auswählen

awk -F "[<>]" '/class="event"/ {i++}i==2{  gsub(/ /,"_"); print $3; exit }' 111
Vielen Dank Huo, funktioniert auch hier mit gezielt nur eine Fundstelle herauszufinden, absolut perfekt!
Gruß an alle Debianer, und immer daran denken:
Macht ohne Haftung funktioniert nicht!

Antworten