suche Dateien mit <speed>WERT GRÖSSER ALS 18.05</speed>

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Benutzeravatar
pachhenk
Beiträge: 120
Registriert: 19.06.2004 15:49:36
Lizenz eigener Beiträge: MIT Lizenz

suche Dateien mit <speed>WERT GRÖSSER ALS 18.05</speed>

Beitrag von pachhenk » 01.02.2024 21:30:27

Ich habe viele GPS-Tracks die von Osmand geschrieben wurden und die Geschwindigkeit (als GPX-Extention) enthalten.

Code: Alles auswählen

</trkpt>
   <trkpt lon="9.53335630" lat="47.60195700">
    <ele>401</ele>
    <time>2018-07-28T13:03:03.000Z</time>
    <hdop>3</hdop>
    <extensions>
     <ql:flags>0</ql:flags>
     <ql:activity>0</ql:activity>
     <speed>4.52</speed>
    </extensions>
   </trkpt>
Und möchte aus diesen die Fahrradfahrten herausfiltern. Als Unterscheidungsmerkmal fällt mir die Geschwindigkeit ein. Ideal wäre der Schnitt (zB unter 25 kmh), aber das ist zu kompliziert.
Wenn ich jedoch alle Dateien mit einer Höchstgeschwindigkeit über 18.05 (=65km/h) rausnehme, bleiben fast nur die geradelten Tracks übrig.

Ich habe mir aus verschiedenen Skripten eines zusammengebastelt, um das Merkmal </speed> zu nutzen und aus all den GPX-Dateien die Tracks rauszufiltern. Hatte mehr Glück als Ahnung, und es funktionierte. :-)

Code: Alles auswählen

mensch@maschine:~$ find /PFAD/ZUM/QUELLVERZEICHNIS/ -name "*.gpx" -print0 | xargs --null grep -l --files-with-match -e "</speed>" | xargs -I '{}' cp '{}' /PFAD/ZUM/ZIELVERZEICHNIS/
Jetzt möchte ich mein Skript umbauen, weiss aber nicht ob und wie es gehen könnte.
Statt nach Dateien mit der Zeichenfolge </speed> suche ich Dateien mit <speed>WERT GRÖSSER ALS </speed>. So könnte ich die meisten Autofahrten rausfiltern und hätte weniger Handarbeit.

Ich habe keine Idee, wie sich das mit find oder grep machen lässt und wäre froh um Hilfe oder Tips.

Benutzeravatar
heisenberg
Beiträge: 3567
Registriert: 04.06.2015 01:17:27
Lizenz eigener Beiträge: MIT Lizenz

Re: suche Dateien mit <speed>WERT GRÖSSER ALS 18.05</speed>

Beitrag von heisenberg » 01.02.2024 23:21:35

XML-Dateien würde ich mit XML-Werkzeugen verarbeiten. Also mit xmllint aus Debianlibxml2-utils oder mit Debianxmlstarlet.

Da der XML-Schnipsel von Dir nicht vollständig ist, kann ich leider damit nicht testen. Du könntest mal eine vollständige Datei einstellen, dann kann man hier konkret anwendbare Beispielbefehle für Deine Daten zeigen.

Wenn ich Dein XML etwas ändere, so dass man das abfragen kann ...

Code: Alles auswählen

<xml>
<trkpt lon="9.53335630" lat="47.60195700">
    <ele>401</ele>
    <time>2018-07-28T13:03:03.000Z</time>
    <hdop>3</hdop>
    <extensions>
     <flags>0</flags>
     <activity>0</activity>
     <speed>4.52</speed>
    </extensions>
</trkpt>
<trkpt lon="9.53335630" lat="47.60195700">
    <ele>402</ele>
    <time>2018-07-28T13:03:03.000Z</time>
    <hdop>3</hdop>
    <extensions>
     <flags>0</flags>
     <activity>0</activity>
     <speed>6.52</speed>
    </extensions>
</trkpt>
<trkpt lon="9.53335630" lat="47.60195700">
    <ele>403</ele>
    <time>2018-07-28T13:03:03.000Z</time>
    <hdop>3</hdop>
    <extensions>
     <flags>0</flags>
     <activity>0</activity>
     <speed>1.52</speed>
    </extensions>
</trkpt>
<trkpt lon="9.53335630" lat="47.60195700">
    <ele>404</ele>
    <time>2018-07-28T13:03:03.000Z</time>
    <hdop>3</hdop>
    <extensions>
     <flags>0</flags>
     <activity>0</activity>
     <speed>9.52</speed>
    </extensions>
</trkpt>
</xml>
... dann kann ich aus dem xml alle "ele"-Elemente herausfinden, bei denen die Geschwindigkeit größer als z. B. "5" ist:

Code: Alles auswählen

$ for file in *.xml;do 
	echo $file
	xmlstarlet sel -t -v '//trkpt[extensions/speed > 5]/ele/text()' "$file"
	# alternativ xmllint:
	# xmllint --xpath '//trkpt[extensions/speed > 5]/ele/text()' "$file"
	echo ""
done

x.xml
402
404
Das //trkpt - Muster wird nach der XPATH-Spezifikation gebildet - eine Abfragesyntax für XML-Daten. Den korrekten Ausdruck hier habe ich mir von ChatGPT geben lassen. Interessant, dass ich trotz ungenauer/falscher Frage (speed ist kein Unterwert von ele) trotzdem eine richtige Lösung bekommen habe.

Siehe:
https://chat.openai.com/share/c83d94cf- ... a3095c3861
Jede Rohheit hat ihren Ursprung in einer Schwäche.

Benutzeravatar
pachhenk
Beiträge: 120
Registriert: 19.06.2004 15:49:36
Lizenz eigener Beiträge: MIT Lizenz

Re: suche Dateien mit <speed>WERT GRÖSSER ALS 18.05</speed>

Beitrag von pachhenk » 02.02.2024 10:00:32

Sorry für die fehlenden Infos und danke für Deine Antwort.
Der Schnipsel entstand, weil ich nicht herausgefunden habe wie ich eine ganze Datei hochladen kann. Und in den Code-block reinkopieren wollt ich sie nicht. Jetzt habe ich No-Paste gefunden, bekomme aber die Antwort "...gpx ist nicht erlaubt".
Deshalb habe ich ein paar Tracks mit denen ich jetzt testen werde hier abgelegt:
https://matterhorn.swisscloudhosting.ch ... ZRpwrxAbzQ

Jetzt versuche ich erst mal Deinen Vorschlag auf diese Dateien anzuwenden und ev. zu verstehen. ;-)

niemand
Beiträge: 503
Registriert: 22.12.2023 16:35:53
Kontaktdaten:

Re: suche Dateien mit <speed>WERT GRÖSSER ALS 18.05</speed>

Beitrag von niemand » 02.02.2024 10:48:37

OT:
pachhenk hat geschrieben: ↑ zum Beitrag ↑
02.02.2024 10:00:32
Jetzt habe ich No-Paste gefunden, bekomme aber die Antwort "...gpx ist nicht erlaubt".
Nachdem es letztlich XML ist, könntest du die Datei einfach mit xml als Endung versehen – dann sollte es funktionieren und richtig dargestellt werden: NoPaste-Eintrag42107
„I fought in the Vim-Emacs-War.“ Quelle

Benutzeravatar
pachhenk
Beiträge: 120
Registriert: 19.06.2004 15:49:36
Lizenz eigener Beiträge: MIT Lizenz

Re: suche Dateien mit <speed>WERT GRÖSSER ALS 18.05</speed>

Beitrag von pachhenk » 02.02.2024 13:55:22

Danke, das hat funktioniert.
pastebin/?mode=view&s=42109&sid=b18131a ... 6364082a58
Aktuell suche ich noch nach der richtigen Syntax um den Code entweder in mein Skrikt zu bauen oder in der Bash zu verwenden.

Code: Alles auswählen

#!/bin/bash
# GPX-Dateien finden mit Geschwindigkeit grösser als ZAHL (m/s)

find . -type f -name "*.gpx" | while read FNAME; do echo $file | xmlstarlet sel -t -v '//trkpt[extensions/speed > 5]/ele/text()' "$file" 
	done

Wer gibt mir diese Antwort:

Code: Alles auswählen

./GPX-speed-groesser-als.sh: Zeile 7: Syntaxfehler: Unerwartetes Dateiende.

xmlstarlet, echo, find oder die Bash?

und

Code: Alles auswählen

$ find . -type f -name "*.gpx" | while read FNAME; do echo $file | xmlstarlet sel -t -v '//trkpt[extensions/speed > 5]/ele/text()' "$file"; done
failed to load external entity ""
führt mich mit "entity" zu der Frage was (von den vielen Übersetzungsmöglichkeiten bei Leo) hier gemeint ist.
Aber ich bin dran...

Benutzeravatar
pachhenk
Beiträge: 120
Registriert: 19.06.2004 15:49:36
Lizenz eigener Beiträge: MIT Lizenz

Re: suche Dateien mit <speed>WERT GRÖSSER ALS 18.05</speed>

Beitrag von pachhenk » 02.02.2024 19:01:48

Zu den beiden gescheiterten Versuchen habe nichts herausfinden können.
Aber ich habe jetzt

Code: Alles auswählen

$ for file in *.xml;do ... 
durch

Code: Alles auswählen

$ for file in DAS VERZEICHNIS MIT DEN TRACKS/*.xml;do 

ersetzt.
Darauf kommen Fehlermeldungen dieser Art:

Code: Alles auswählen

Test-Tracks/2023-05-31_07-24_Wed.xml:46485.21: Namespace prefix osmand on heading is not defined
     <osmand:heading>0</osmand:heading>
                    ^
:?
Ich glaub da habe ich mich übernommen.
Bin wohl schneller wenn ich die Dateien in QMapshack lade und von hand sortiere...

niemand
Beiträge: 503
Registriert: 22.12.2023 16:35:53
Kontaktdaten:

Re: suche Dateien mit <speed>WERT GRÖSSER ALS 18.05</speed>

Beitrag von niemand » 02.02.2024 22:36:17

pachhenk hat geschrieben: ↑ zum Beitrag ↑
02.02.2024 19:01:48
Bin wohl schneller wenn ich die Dateien in QMapshack lade und von hand sortiere.
Kommt drauf an. Wenn’s nur ein paar Dateien sind, schon. Wenn’s ein paar mehr Files sind, ist das eine gute Gelegenheit, zu lernen. Ich persönlich hätte in dem Fall zu Python gegriffen, btw., aber das ist wohl nur persönliche Präferenz.

In deinem Fall: auch Shellscripte können mehrere Zeilen und insbesondere Variablen haben – nutze das am besten, Fehler sind so viel(!) leichter zu finden und zu beheben.
„I fought in the Vim-Emacs-War.“ Quelle

Benutzeravatar
GregorS
Beiträge: 2629
Registriert: 05.06.2008 09:36:37
Wohnort: Freiburg
Kontaktdaten:

Re: suche Dateien mit <speed>WERT GRÖSSER ALS 18.05</speed>

Beitrag von GregorS » 02.02.2024 22:44:49

pachhenk hat geschrieben: ↑ zum Beitrag ↑
02.02.2024 19:01:48
Ich glaub da habe ich mich übernommen.
Bin wohl schneller wenn ich die Dateien in QMapshack lade und von hand sortiere...
Nu wirf mal nicht gleich die Flinte ins Korn. XML-Dateien sind kein Hexenwerk, die o.g. Tools ziemlich sicher auch nicht (siehe Posting von Heisenberg). Der Code, den er dort zeigt, sieht doch schon mal vielversprechend aus.

Ein bisschen XML-Wissen wirst Du Dir aneignen müssen (meiner Meinung nach halb so wild) und das Lesen/Überfliegen der man-Pages zu den Tools, die man benutzt, gehört ja eigentlich auch dazu, wenn man in Linux einsteigt.

Na, und wenn Du Fragen hast, dann frag'. So verkehrt bist Du hier nicht :-)

Gruß

Gregor

PS: Ich bin durch den Tipp von Heisenberg erst auf xmlstarlet aufmerksam geworden. Das scheint mir für Deinen Zweck sehr gut geeignet zu sein.
Wenn man keine Probleme hat, kann man sich welche machen. ("Großes Lötauge", Medizinmann der M3-Hopi [und sog. Maker])

Benutzeravatar
Phineas
Beiträge: 348
Registriert: 20.06.2012 20:26:19

Re: suche Dateien mit <speed>WERT GRÖSSER ALS 18.05</speed>

Beitrag von Phineas » 02.02.2024 23:28:15

Dieser extrem intolerante Einzeiler könnte Dir die Dateinamen schon liefern, die Du suchst:

Code: Alles auswählen

find /PFAD/ZUM/QUELLVERZEICHNIS/ -name "*.gpx" | awk '{file=$0;while((getline line<file)>0){if(match(line,"<speed>.*</speed>")){sub(".*<speed>","",line);sub("</speed>","",line);if(strtonum(line)>18.05){print file;quit}}}}'
Das kannst Du, wie in Deinem Eingangspost gezeigt, mittels Pipe, xargs und cp weiterverarbeiten.

An der Toleranz (z.B. <SPEED> statt <speed>) können wir noch feilen.
Die größte Toleranz erreicht man aber natürlich mit dem Tipp von heisenberg. Parsen ist da halt besser als Textfiltern.

Benutzeravatar
heisenberg
Beiträge: 3567
Registriert: 04.06.2015 01:17:27
Lizenz eigener Beiträge: MIT Lizenz

Re: suche Dateien mit <speed>WERT GRÖSSER ALS 18.05</speed>

Beitrag von heisenberg » 02.02.2024 23:47:08

Das mit den Namespaces finde ich immer komisch. Ich kann mir das nächste Woche nochmal anschauen.

Quick'n'Dirty wäre auch hier die Namespaces per sed zu entfernen.

Google liefert ansonsten zu den konkreten Fehlermeldungen Ergebnisse. Weitere Möglichkeit wäre, auch noch mal ChatGPT zu befragen.

Desweiteren denke ich schon, dass man das auch ohne XML-Parsing gut hinbekommt. Vielleicht als Vorbehandlung per tr alles in Groß- oder Kleinbuchstaben umwandeln und dann mit awk den höchsten Speed-Wert rauspuhlen.

Nachtrag:

Bzgl. der XML-Spezifikation ist das eine ungültige XML-Datei. Zum Osmand-Namespace fehlt die Definition (DTD). Die anderen XML-Namespaces haben eine DTD im Kopfbereich der Datei. Da gibt's auch Bugreports zu.

...und eine ungültige XML-Datei kann man mit XML-Tools halt auch erst Mal nicht parsen.
Zuletzt geändert von heisenberg am 03.02.2024 00:28:37, insgesamt 1-mal geändert.
Jede Rohheit hat ihren Ursprung in einer Schwäche.

Benutzeravatar
Phineas
Beiträge: 348
Registriert: 20.06.2012 20:26:19

Re: suche Dateien mit <speed>WERT GRÖSSER ALS 18.05</speed>

Beitrag von Phineas » 03.02.2024 00:25:15

heisenberg hat geschrieben: ↑ zum Beitrag ↑
02.02.2024 23:47:08
Vielleicht als Vorbehandlung per tr alles in Groß- oder Kleinbuchstaben umwandeln und dann mit awk den höchsten Speed-Wert rauspuhlen.
Das kann awk auch ohne tr. Wie schon geschrieben: An der (Fehler)Toleranz können wir noch feilen. Gerne sogar, das hält den alten Kopp noch etwas frisch. :D

Benutzeravatar
heisenberg
Beiträge: 3567
Registriert: 04.06.2015 01:17:27
Lizenz eigener Beiträge: MIT Lizenz

Re: suche Dateien mit <speed>WERT GRÖSSER ALS 18.05</speed>

Beitrag von heisenberg » 03.02.2024 02:12:28

So bekommt man die GPX zu einem validen XML :

Code: Alles auswählen

sed -re 's#(<gpx )#\1xmlns:osmand="empty" #i' file.gpx
D. h. man fügt eine leere Namespace-Definition für "osmand" hinter "<gpx " ein. Die Datei selbst wird dabei nicht verändert. Die veränderte Version wird nur ausgegeben.

So holt man sich die Speed-Werte aus der Datei:

Code: Alles auswählen

xmlstarlet sel -t -v '//osmand:speed/text()'
Und so bekommt man widerum dann den größten Speed-Wert von allen:

Code: Alles auswählen

awk '$1 > max {max=$1} END {print max}'
Zusammengefasst als Bash-Funktion:

Code: Alles auswählen

get_max_speed_from_gpx() {

   local filename="$1"
   
   sed -re 's#(<gpx )#\1xmlns:osmand="empty" #i' "$filename" \
      | xmlstarlet sel -t -v '//osmand:speed/text()' \
      | awk '$1 > max {max=$1} END {print max}'
}
Die Daten werden hier von einem Prozess an den nächsten übergeben über die Pipe ( "|" ). sed übergibt die geänderten XML-Daten an xmlstarlet, was dann widerum nur die Speedwerte an awk übergibt, welches schließlich nur den höchsten davon ausgibt.

Zum Schluß noch ein Schleifchen drum herum:

Code: Alles auswählen

while read filename ; do
   echo "$filename"
   get_max_speed_from_gpx "$filename"
done < <( find /dein/pfad -iname *.gpx )
Damit dürftest Du schon fast am Ziel sein.

Das ist dann das aktuelle ganze Bash-Script:

Code: Alles auswählen

#!/bin/bash

get_max_speed_from_gpx() {

   local filename="$1"
   
   sed -re 's#(<gpx )#\1xmlns:osmand="empty" #i' "$filename" \
      | xmlstarlet sel -t -v '//osmand:speed/text()' \
      | awk '$1 > max {max=$1} END {print max}'
}

while read filename ; do

   echo "$filename"
   get_max_speed_from_gpx "$filename"
   
done < <( find /dein/pfad -iname "*.gpx" )
Nachtrag: Quotes um das "*.gpx" haben noch gefehlt.
Zuletzt geändert von heisenberg am 04.02.2024 15:14:49, insgesamt 2-mal geändert.
Jede Rohheit hat ihren Ursprung in einer Schwäche.

Benutzeravatar
pachhenk
Beiträge: 120
Registriert: 19.06.2004 15:49:36
Lizenz eigener Beiträge: MIT Lizenz

Re: suche Dateien mit <speed>WERT GRÖSSER ALS 18.05</speed>

Beitrag von pachhenk » 03.02.2024 13:31:37

@ niemand und GregorS:
Ja Ihr habt recht. Und mir gefällt das. Suchen, Manuals lesen, probieren, und plötzlich machts wieder mal klick... :-)
Meine Ressourcen sind allerdings noch anderweitig eingeplant. Sonst würde ich nicht immer noch solche Themen starten, wo ich doch schon vor 20 Jahren mit dem PowerPack von Ganten gestartet bin... ;-)
Aber danke für eure Ermutigung.
Phineas und Heisenberg haben ja auch nochmal richtig nachgelegt. ;-) Diese Hausaufgaben sind zu verlockend um sie liegen zu lassen...

Benutzeravatar
pachhenk
Beiträge: 120
Registriert: 19.06.2004 15:49:36
Lizenz eigener Beiträge: MIT Lizenz

Re: suche Dateien mit <speed>WERT GRÖSSER ALS 18.05</speed>

Beitrag von pachhenk » 03.02.2024 13:35:04

@ Phineas und Heisenberg:
Wow, danke fürs input!

Code: Alles auswählen

mensch@maschine:~/Verzeichnis$ ./Bash--Script_Heisenberg.sh 
./Bash--Script_Heisenberg.sh: Zeile 9: Dateiende beim Suchen nach »'« erreicht.
Deshalb habe ich ans Ende von Zeile 9 ein "'" gesetzt. Scheint zu stimmen, denn die Farben sind "ordentlicher" und es geht ein Stück weiter:

Code: Alles auswählen

mensch@maschine:~/Verzeichnis$ ./Bash--Script_Heisenberg_modHH.sh 
find: paths must precede expression: `2015-06-06 07-21 Sa..gpx'
find: possible unquoted pattern after predicate `-iname'?
Danke an find für den Tip! :-)
Also habe ich in Zeile 17 vor das *.gpx ein \ gesetzt.

Code: Alles auswählen

mensch@maschine:~/Verzeichnis$ ./Bash--Script_Heisenberg_modHH.sh 
./2015-06-06 07-21 Sa..gpx

./2023-05-31_07-24_Wed.gpx
16.9
./2016-04-25 15-50 Mo..gpx

./2018-04-17 09-16 Tue.gpx

./2020-09-18_08-58_Fri.gpx

./2019-09-17_20-02_Tue.gpx

./2017-08-15 09-42 Tue.gpx

./2014-03-30 05-54 So..gpx

Ich bin also ein gutes Stück weiter und melde mich wenns Ergebnisse gibt oder neue Fragen...

Benutzeravatar
pachhenk
Beiträge: 120
Registriert: 19.06.2004 15:49:36
Lizenz eigener Beiträge: MIT Lizenz

Re: suche Dateien mit <speed>WERT GRÖSSER ALS 18.05</speed>

Beitrag von pachhenk » 03.02.2024 22:58:05

Phineas hat geschrieben: ↑ zum Beitrag ↑
02.02.2024 23:28:15
Dieser extrem intolerante Einzeiler könnte Dir die Dateinamen schon liefern, die Du suchst:

Code: Alles auswählen

find /PFAD/ZUM/QUELLVERZEICHNIS/ -name "*.gpx" | awk '{file=$0;while((getline line<file)>0){if(match(line,"<speed>.*</speed>")){sub(".*<speed>","",line);sub("</speed>","",line);if(strtonum(line)>18.05){print file;quit}}}}'
....
Ich bekomme hier die Ausgabe

Code: Alles auswählen

awk: line 2: function strtonum never defined
Getestet habe ich es mit dem file das ich in No-Paste hochgeladen hatte. An der Datei liegt es aber auch nicht, denn die Ausgabe kommt selbst wenn ich den Befehl in einem leeren Verzeichnis ausführe.
Bin auf einem aktuellen bookworm und meine awk Version ist 1.3.4.
Zu strtonum finde ich nur texte, die ich nicht verstehe. :|

Benutzeravatar
pachhenk
Beiträge: 120
Registriert: 19.06.2004 15:49:36
Lizenz eigener Beiträge: MIT Lizenz

Re: suche Dateien mit <speed>WERT GRÖSSER ALS 18.05</speed>

Beitrag von pachhenk » 03.02.2024 23:07:53

heisenberg hat geschrieben: ↑ zum Beitrag ↑
03.02.2024 02:12:28
...
Das ist dann das aktuelle ganze Bash-Script:

Code: Alles auswählen

#!/bin/bash

get_max_speed_from_gpx() {

   local filename="$1"
   
   sed -re 's#(<gpx )#\1xmlns:osmand="empty" #i' "$filename" \
      | xmlstarlet sel -t -v '//osmand:speed/text()' \
      | awk '$1 > max {max=$1} END {print max}'
}

while read filename ; do

   echo "$filename"
   get_max_speed_from_gpx "$filename"
   
done < <( find /dein/pfad -iname *.gpx )
Die Ausgabe bei mir enthält nur zu einem Track eine Geschwindigkeitsangabe (16.9)

Code: Alles auswählen

mensch@maschine:~/Verzeichnis$ ./Bash--Script_Heisenberg_modHH.sh 
./2015-06-06 07-21 Sa..gpx

./2023-05-31_07-24_Wed.gpx
16.9
./2016-04-25 15-50 Mo..gpx

./2018-04-17 09-16 Tue.gpx

./2020-09-18_08-58_Fri.gpx

./2019-09-17_20-02_Tue.gpx

./2017-08-15 09-42 Tue.gpx

./2014-03-30 05-54 So..gpx
Ich habe die anderen durchgeschaut und kann keinen Grund dafür finden.
Meinen eingefügten Backslash habe ich nochmal weggelassen bzw durch Maskierung mit " ersetzt. Das Ergebnis ist das gleiche.
Sehe ich das richtig, dass Du das "'" übernommen hast und den "\" nicht? Oder hatte ich da am Anfang falsch geschaut?

Benutzeravatar
heisenberg
Beiträge: 3567
Registriert: 04.06.2015 01:17:27
Lizenz eigener Beiträge: MIT Lizenz

Re: suche Dateien mit <speed>WERT GRÖSSER ALS 18.05</speed>

Beitrag von heisenberg » 04.02.2024 09:16:40

pachhenk hat geschrieben:Die Ausgabe bei mir enthält nur zu einem Track eine Geschwindigkeitsangabe (16.9)
Na dann gehe wieder Schritte zurück. Schaue Dir die XML-Dateien an. Weisen die Unterschiede auf? Bringen Teilbefehle da Fehlermeldungen? Führe das schrittweise aus. Das wichtigste wäre der xmlstarlet-Befehl.

Code: Alles auswählen

awk: line 2: function strtonum never defined
Bzgl. awk gibt es da verschiedene Versionen. Debianmawk ist da näher dran am Original. Dann gibt's da noch GNU awk - Paket Debiangawk - mit deutlich erweitertem Funktionsumfang. Ich würde mal vermuten, dass tonumber eine gawk - Funktion ist, Du aber mawk installiert hast.
Jede Rohheit hat ihren Ursprung in einer Schwäche.

Benutzeravatar
heisenberg
Beiträge: 3567
Registriert: 04.06.2015 01:17:27
Lizenz eigener Beiträge: MIT Lizenz

Re: suche Dateien mit <speed>WERT GRÖSSER ALS 18.05</speed>

Beitrag von heisenberg » 04.02.2024 14:52:52

Ich habe mir nochmal die XML-Dateien angeschaut. Wir haben es hier mit zwei verschiedenen XML-Formaten zu tun. Das legen ja auch die Jahreszahlen nahe, dass die Speicherformate von stark unterschiedlichen Programmversionen stammen.

Die mit der gewünschten Ausgabe sieht so aus:

Code: Alles auswählen

...
     <osmand:speed>1</osmand:speed>
...
Die ohne Ausgaben sehen so aus:

Code: Alles auswählen

...
     <speed>0.7099999785423279</speed>
...
D. h. da ist kein expliziter Namespace angegeben.

Einen weiteren Unterschied gibt es noch:

Die Dateien ohne den expliziten "osmand" - Namespace, haben einen default Namespace für die XML-Datei im Header gesetzt:

Code: Alles auswählen

<gpx ... xmlns="http://www.topografix.com/GPX/1/1">
... und wenn die Namespaces nicht in das XPath-Muster mit einbezogen sind, dann trifft der Ausdruck da genau gar nicht zu!

Dafür gibt's zwei unterschiedliche Lösungswege, je nachdem, ob man mit xmllint oder xmlstarlet arbeitet:

xmlstarlet

Code: Alles auswählen

xmlstarlet sel -N x="http://www.topografix.com/GPX/1/1" -t -v "//x:speed/text()" datei.gpx
Man definiert hier den Namespace mit einer Abkürzung("x") und sucht in dem Namespace dann nach "speed".

xmllint

Code: Alles auswählen

xmllint --xpath "//*[local-name()='speed']/text()" datei.gpx
xmllint kann wohl keine Namespaces definieren. Insofern arbeitet man mit einem Wildcard und dem "local-name", also dem Attributnamen der losgelöst vom Namespace zutreffen kann. Das funktioniert auch für xmlstarlet und ist generisch für alle Fälle unabhängig von den Namespaces.

Das ist dann das aktuelle Script:

Code: Alles auswählen

#!/bin/bash

get_max_speed_from_gpx() {

   local filename="$1"
   
   sed -re 's#(<gpx )#\1xmlns:osmand="empty" #i' "$filename" \
      | xmlstarlet sel -t -v "//*[local-name()='speed']/text()" - \
      | awk '$1 > max {max=$1} END {print max}'
}

while read filename ; do

   echo "$filename"
   get_max_speed_from_gpx "$filename"
   
done < <( find . -iname "*.gpx" )
Anmerkung: Quotes um das "*.gpx" haben oben noch gefehlt.

Oder doch lieber quick'n'dirty mit awk (GNU-awk!) ?

Code: Alles auswählen

#!/bin/bash

find . -iname "*.gpx" -exec gawk -v thresh=18 '
	match(tolower($0),"speed[\\s>]+(.*)[\\s<]+/speed",m) {
		if (m[1]>thresh ){
			print FILENAME,m[1];exit}
		}' {} \;
Ansonsten ist XML-Verarbeitung mit awk nicht besonders sicher. Wenn z. B. die XML-Datei komprimiert ist, d. h. alles in einer Zeile ohne überflüssigen Whitespace, dann funktioniert das hier mit awk überhaupt nicht. Ein prophylaktischer Pretty-Print vorab wäre grundsätzlich zu empfehlen:

Code: Alles auswählen

xmllint --format datei.xml | awk ...
Zuletzt geändert von heisenberg am 04.02.2024 17:15:53, insgesamt 6-mal geändert.
Jede Rohheit hat ihren Ursprung in einer Schwäche.

Benutzeravatar
Phineas
Beiträge: 348
Registriert: 20.06.2012 20:26:19

Re: suche Dateien mit <speed>WERT GRÖSSER ALS 18.05</speed>

Beitrag von Phineas » 04.02.2024 15:21:14

Ups, awk ist bei mir nur ein Link auf gawk. Das sollte ich mir mal angewöhnen, auch so zu schreiben. Also:

Code: Alles auswählen

find ./ -name "*.gpx" | gawk '{file=$0;while((getline line<file)>0){if(match(line,"<speed>.*</speed>")){sub(".*<speed>","",line);sub("</speed>.*","",line);if(strtonum(line)>18.05){print file;quit}}}}'

Benutzeravatar
heisenberg
Beiträge: 3567
Registriert: 04.06.2015 01:17:27
Lizenz eigener Beiträge: MIT Lizenz

Re: suche Dateien mit <speed>WERT GRÖSSER ALS 18.05</speed>

Beitrag von heisenberg » 04.02.2024 15:38:55

Ich habe Phineas' awk-Lösung mal etwas anders formatiert:

Code: Alles auswählen

find ./ -name "*.gpx" | gawk '
    {
      file=$0
      while((getline line<file)>0) {
        if(match(line,"<speed>.*</speed>")){
          sub(".*<speed>","",line)
          sub("</speed>.*","",line)
          if(strtonum(line)>18.05){
            print file;quit
          }
        }       
      }     
    }' 
Ich finde, so lässt sich das viel leichter verstehen.
Jede Rohheit hat ihren Ursprung in einer Schwäche.

Benutzeravatar
Phineas
Beiträge: 348
Registriert: 20.06.2012 20:26:19

Re: suche Dateien mit <speed>WERT GRÖSSER ALS 18.05</speed>

Beitrag von Phineas » 05.02.2024 00:24:19

Danke! :THX:

So zeigt sich auch prima, dass es ein ganz trivialer Code ist, ganz ohne Awk-Spezialitäten (z.B. awk '!a[$0]++').

Benutzeravatar
pachhenk
Beiträge: 120
Registriert: 19.06.2004 15:49:36
Lizenz eigener Beiträge: MIT Lizenz

Re: suche Dateien mit <speed>WERT GRÖSSER ALS 18.05</speed>

Beitrag von pachhenk » 05.02.2024 07:08:52

heisenberg hat geschrieben: ↑ zum Beitrag ↑
04.02.2024 09:16:40
...
Bzgl. awk gibt es da verschiedene Versionen. Debianmawk ist da näher dran am Original. Dann gibt's da noch GNU awk - Paket Debiangawk - mit deutlich erweitertem Funktionsumfang. Ich würde mal vermuten, dass tonumber eine gawk - Funktion ist, Du aber mawk installiert hast.
Du hast recht ich habe mawk.

Benutzeravatar
pachhenk
Beiträge: 120
Registriert: 19.06.2004 15:49:36
Lizenz eigener Beiträge: MIT Lizenz

Re: suche Dateien mit <speed>WERT GRÖSSER ALS 18.05</speed>

Beitrag von pachhenk » 05.02.2024 07:10:57

heisenberg hat geschrieben: ↑ zum Beitrag ↑
04.02.2024 14:52:52
...
Das ist dann das aktuelle Script:

Code: Alles auswählen

#!/bin/bash

get_max_speed_from_gpx() {

   local filename="$1"
   
   sed -re 's#(<gpx )#\1xmlns:osmand="empty" #i' "$filename" \
      | xmlstarlet sel -t -v "//*[local-name()='speed']/text()" - \
      | awk '$1 > max {max=$1} END {print max}'
}

while read filename ; do

   echo "$filename"
   get_max_speed_from_gpx "$filename"
   
done < <( find . -iname "*.gpx" )
...
Was soll ich sagen?
DANKE!

Die neue Version lief perfekt durch. Auch in der grossen Sammlung alle mit Ausgabe der MaxSpeed. Ds Ergenis kann ich jetzt weiterverarbeiten und bin zuversichtlich, dass ich das hinkrieg. Mal sehen... ;-)

Benutzeravatar
pachhenk
Beiträge: 120
Registriert: 19.06.2004 15:49:36
Lizenz eigener Beiträge: MIT Lizenz

Re: suche Dateien mit <speed>WERT GRÖSSER ALS 18.05</speed>

Beitrag von pachhenk » 05.02.2024 07:12:41

Phineas hat geschrieben: ↑ zum Beitrag ↑
05.02.2024 00:24:19
Danke! :THX:

So zeigt sich auch prima, dass es ein ganz trivialer Code ist, ganz ohne Awk-Spezialitäten (z.B. awk '!a[$0]++').
Vom "trivialen Code" hatte ich eben ursprünglich geträumt. Sonst hätte ich dieses Projekt gar nicht angestossen... ;-)

niemand
Beiträge: 503
Registriert: 22.12.2023 16:35:53
Kontaktdaten:

Re: suche Dateien mit <speed>WERT GRÖSSER ALS 18.05</speed>

Beitrag von niemand » 05.02.2024 10:36:49

pachhenk hat geschrieben: ↑ zum Beitrag ↑
05.02.2024 07:12:41
Vom "trivialen Code" hatte ich eben ursprünglich geträumt.
Wenn’s wirklich trivial werden soll, wäre vielleicht Python einen Blick wert? Da ließe sich die vorliegende Aufgabe mit Bordmitteln lösen, und hübsch lesbar wär’s auch.
„I fought in the Vim-Emacs-War.“ Quelle

Antworten