폴더에 여러 개의 .tcx 파일(기본적으로 GPS 장치 출력 XML 파일)이 있습니다. 이름 지정 규칙 DATE_LOCATION_SPORT.tcx를 따릅니다. 각 파일에는 초당 기록되는 주요 GPS 데이터를 기록하는 여러 개의 트랙 포인트 노드가 있으며, 그 안에 "DistanceMeters"라는 하위 거리 노드가 있습니다. 각 파일을 살펴보고 마지막 "DistanceMeters" 노드를 찾은 다음 해당 거리 목록을 출력하고 싶습니다. 다음은 파일의 일부입니다. (저는 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>
…
나는 단 하나의 파일로 이 작업을 수행하는 것으로 시작했습니다(참고: 일부 파일 이름에는 공백이 포함되어 있는데 이로 인해 문제가 발생하는지 확실하지 않습니다).
grep '<DistanceMeters>.*<\/DistanceMeters>' '2017-03-23_Somewhere_Running.tcx' | tail -1 | grep -o '[0-9]\+\.[0-9]\+'
마지막 "DistanceMeters" 노드를 매우 훌륭하게 얻은 다음 grep을 사용하여 xml의 전체 라인이 아닌 숫자 거리를 가져옵니다.
find . -iname '2017*_Running.tcx'
위의 내용은 올해 제가 관심을 갖고 있는 모든 파일의 목록을 제공합니다.
하지만 명령을 결합하려고 하면 모든 것이 무너집니다. "\;"로 끝나지 않는다는 오류가 발생합니다. 또는 답변을 얻었지만 각 파일에 대한 거리가 아니라 파일 목록의 마지막 파일에 대한 마지막 거리 값만 얻었습니다.
따라서 이것은 목록에 있는 마지막 파일의 최종 거리를 제공합니다.
find . -iname '*_Running.tcx' -print0 | xargs -0 grep '<DistanceMeters>.*<\/DistanceMeters>' | tail -1 | grep -o '[0-9]\+\.[0-9]\+'
이것도 마찬가지입니다.
find . -iname '*_Running.tcx' -exec grep '<DistanceMeters>.*<\/DistanceMeters>' {} \; | tail -1 | grep -o '[0-9]\+\.[0-9]\+'
다양한 조합을 시도했지만 필요한 방식으로 조합하는 방법을 잘 모르겠습니다. 나는 아마도 "\;"를 넣을 것이라고 생각했습니다. 결국에는 그렇게 하겠지만 작동하지 않습니다. ";"로 끝나지 않는다고 불평합니다. 또는 "+".
find . -iname '*_Running.tcx' -exec grep '<DistanceMeters>.*<\/DistanceMeters>' {} | tail -1 | grep -o '[0-9]\+\.[0-9]\+' \;
수확량
grep: ;: No such file or directory
find: -exec: no terminating ";" or "+"
어떤 아이디어가 있나요?
여기까지 읽어주셔서 감사합니다!
답변1
여기서 문제는 인용에 있습니다... find(1)의 'exec' 옵션이 명령 파이프라인을 허용하도록 이것을 올바르게 인용하는 방법이 있는지 모르겠습니다.
이 문제를 해결하는 한 가지 방법은 다음과 같습니다.
$ for rfile in $(find . -iname '2017*_Running.tcx'); do grep '<DistanceMeters>.*<\/DistanceMeters>' $rfile | tail -1 | grep -o '[0-9]\+\.[0-9]\+'; done