フォルダー内に .tcx ファイル (基本的には GPS デバイスが出力した XML ファイル) が多数あります。これらは、命名規則 DATE_LOCATION_SPORT.tcx に従っています。各ファイルには、1 秒ごとに記録された主要な GPS データを示すトラック ポイント ノードが多数あり、その中には「DistanceMeters」と呼ばれる子の距離ノードがあります。各ファイルを grep して、最後の「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>
…
まず、1 つのファイルだけでこれを実行しようとしました (一部のファイル名にはスペースが含まれていることに注意してください。これが問題の原因かどうかはわかりません)。
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' オプションがコマンドのパイプラインを受け入れるようにこれを正しく引用符で囲む方法があるかどうかはわかりません。
この問題を回避する方法の 1 つを次に示します。
$ for rfile in $(find . -iname '2017*_Running.tcx'); do grep '<DistanceMeters>.*<\/DistanceMeters>' $rfile | tail -1 | grep -o '[0-9]\+\.[0-9]\+'; done