Tengo un montón de archivos .tcx (esencialmente un archivo XML generado por un dispositivo GPS) en una carpeta. Siguen la convención de nomenclatura DATE_LOCATION_SPORT.tcx. Cada archivo tiene un conjunto de nodos de puntos de seguimiento que anotan datos clave de GPS registrados cada segundo, dentro de los cuales hay un nodo secundario de distancia hasta el momento llamado "DistanceMeters". Quiero revisar cada archivo, encontrar el último nodo "DistanceMeters" y luego generar esa lista de distancias. Aquí hay un fragmento de un archivo. (Estoy usando el terminal OS X Sierra)
…
<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>
…
Comencé intentando hacer esto con un solo archivo (tenga en cuenta que algunos de los nombres de archivos tienen espacios, no estoy seguro si esto me está haciendo tropezar);
grep '<DistanceMeters>.*<\/DistanceMeters>' '2017-03-23_Somewhere_Running.tcx' | tail -1 | grep -o '[0-9]\+\.[0-9]\+'
Lo cual obtiene muy bien el último nodo "DistanceMeters" y luego usa grep para extraer la distancia numérica en lugar de toda la línea de xml.
find . -iname '2017*_Running.tcx'
Lo anterior me da una lista de todos los archivos que me interesan para este año.
Pero cuando intento combinar los comandos, todo se desmorona. Recibo un error que indica que no termina en "\;" o obtengo una respuesta, pero solo el último valor de distancia para el último archivo en la lista de archivos, en lugar de una distancia para cada uno.
Entonces esto me da la distancia final del último archivo de la lista;
find . -iname '*_Running.tcx' -print0 | xargs -0 grep '<DistanceMeters>.*<\/DistanceMeters>' | tail -1 | grep -o '[0-9]\+\.[0-9]\+'
Al igual que esto;
find . -iname '*_Running.tcx' -exec grep '<DistanceMeters>.*<\/DistanceMeters>' {} \; | tail -1 | grep -o '[0-9]\+\.[0-9]\+'
He probado varias combinaciones, pero no estoy seguro de cómo combinarlas como necesito. Pensé que tal vez poner el "\;" al final lo haría, pero esto no funciona; se queja de que no termina en ";" o "+".
find . -iname '*_Running.tcx' -exec grep '<DistanceMeters>.*<\/DistanceMeters>' {} | tail -1 | grep -o '[0-9]\+\.[0-9]\+' \;
rendimientos
grep: ;: No such file or directory
find: -exec: no terminating ";" or "+"
¿Algunas ideas?
¡Gracias por leer hasta aquí!
Respuesta1
El problema aquí es con las comillas... No sé si hay una manera de citar esto correctamente para que la opción 'exec' de find(1) acepte una cadena de comandos.
Aquí hay una forma de solucionar ese problema:
$ for rfile in $(find . -iname '2017*_Running.tcx'); do grep '<DistanceMeters>.*<\/DistanceMeters>' $rfile | tail -1 | grep -o '[0-9]\+\.[0-9]\+'; done