Ich habe eine Reihe von .tcx-Dateien (im Wesentlichen eine von einem GPS-Gerät ausgegebene XML-Datei) in einem Ordner. Sie folgen der Namenskonvention DATE_LOCATION_SPORT.tcx. Jede Datei hat eine Reihe von Trackpoint-Knoten, die wichtige GPS-Daten notieren, die jede Sekunde aufgezeichnet werden, innerhalb derer sich ein untergeordneter Knoten für die bisherige Distanz namens „DistanceMeters“ befindet. Ich möchte jede Datei durchsuchen und den letzten Knoten „DistanceMeters“ finden und dann diese Liste der Distanzen ausgeben. Hier ist ein Ausschnitt aus einer Datei. (Ich verwende das OS X Sierra-Terminal)
…
<Trackpoint>
<Time>2017-04-09T08:15:29.000Z</Time>
<Position>
<LatitudeDegrees>0.123456</LatitudeDegrees>
<LongitudeDegrees>-0.654321</LongitudeDegrees>
</Position>
<AltitudeMeters>24.363636363636363</AltitudeMeters>
<DistanceMeters>1382.3235298511217</DistanceMeters>
<HeartRateBpm xsi:type="HeartRateInBeatsPerMinute_t">
<Value>130</Value>
</HeartRateBpm>
</Trackpoint>
…
Ich habe zunächst versucht, dies mit nur einer Datei zu tun (beachten Sie, dass einige der Dateinamen Leerzeichen enthalten, ich bin nicht sicher, ob mich das verwirrt).
grep '<DistanceMeters>.*<\/DistanceMeters>' '2017-03-23_Somewhere_Running.tcx' | tail -1 | grep -o '[0-9]\+\.[0-9]\+'
Dadurch wird sehr gut der letzte Knoten „DistanceMeters“ abgerufen und anschließend mithilfe von grep die numerische Distanz und nicht die gesamte XML-Zeile abgerufen.
find . -iname '2017*_Running.tcx'
Oben finden Sie eine Liste aller Dateien, die mich für dieses Jahr interessieren.
Aber wenn ich versuche, die Befehle zu kombinieren, fällt alles auseinander. Entweder bekomme ich eine Fehlermeldung, dass die Befehle nicht mit "\;" enden, oder ich bekomme eine Antwort, aber nur den letzten Distanzwert für die letzte Datei in der Dateiliste, statt einer Distanz für jede Datei.
Dadurch erhalte ich die endgültige Entfernung der letzten Datei in der Liste.
find . -iname '*_Running.tcx' -print0 | xargs -0 grep '<DistanceMeters>.*<\/DistanceMeters>' | tail -1 | grep -o '[0-9]\+\.[0-9]\+'
Genauso wie dies;
find . -iname '*_Running.tcx' -exec grep '<DistanceMeters>.*<\/DistanceMeters>' {} \; | tail -1 | grep -o '[0-9]\+\.[0-9]\+'
Ich habe verschiedene Kombinationen ausprobiert, bin mir aber nicht sicher, wie ich sie am besten kombinieren soll. Ich dachte, vielleicht würde es funktionieren, wenn ich am Ende ein "\;" einfüge, aber das funktioniert nicht – es wird bemängelt, dass es nicht mit ";" oder "+" endet.
find . -iname '*_Running.tcx' -exec grep '<DistanceMeters>.*<\/DistanceMeters>' {} | tail -1 | grep -o '[0-9]\+\.[0-9]\+' \;
Erträge
grep: ;: No such file or directory
find: -exec: no terminating ";" or "+"
Irgendwelche Ideen?
Danke, dass Sie bis hierher gelesen haben!
Antwort1
Das Problem liegt hier beim Zitieren ... Ich weiß nicht, ob es eine Möglichkeit gibt, dies korrekt zu zitieren, sodass die Option „exec“ für find(1) eine Befehlspipeline akzeptiert.
So können Sie dieses Problem umgehen:
$ for rfile in $(find . -iname '2017*_Running.tcx'); do grep '<DistanceMeters>.*<\/DistanceMeters>' $rfile | tail -1 | grep -o '[0-9]\+\.[0-9]\+'; done