例 00:03:03.333、00:01:01.111、00:02:02.222 の和を変数に入れる方法
EPOCH='jan 1 1970'
offset=$EPOCH
lsdvd -c VIDEO_TS | grep "Length:" | grep "Chapter:" | awk '{print($4)}' | while read -r len
do
len=${len:0:12}
offset="$(date -u -d "$EPOCH $len" +%T.%3N) + $(date -u -d "$offset" +%T.%3N)"
echo "need sum" $offset "then" ffmpeg -ss $offset ... -t $len ...
done
答え1
bc
shは整数演算のみを実行できるため、他のもの(またはawkやPerlなどの非整数演算を実行できる言語)を使用する必要があります。
を使用するには、bc
まずフォーマット%H:%M:%S。%3Nを秒(小数部を含む)に変換してからパイプする必要がありますbc
。
たとえば、
#!/bin/bash
epoch='1970-01-01'
len1='00:01:01.111'
len2='00:02:02.222'
# convert to seconds
len1_s=$(date -u -d "$epoch $len1" '+%s.%3N')
len2_s=$(date -u -d "$epoch $len2" '+%s.%3N')
# add the seconds
sum_s=$( echo "$len1_s + $len2_s" | bc )
echo $len1_s + $len2_s = $sum_s
# convert back to H:M:S.N
sum=$(date -u -d "@$sum_s" '+%T.%3N')
echo $len1 + $len2 = $sum
出力:
$ ./sum.sh
61.111 + 122.222 = 183.333
00:01:01.111 + 00:02:02.222 = 00:03:03.333
実装はしばらくあなたに任せます...しかし、ここにはlsdvd
数秒で長さを提供するいくつかの便利な出力オプションがあることに注意してください(したがって変換する必要はありません)。おそらく最も便利なのは、章の長さを処理xmlstarlet
または抽出するために使用できるXML出力オプションです。xml2
たとえば、ここのXML出力を行ベースのlsdvd
形式(awkまたは他の手段を使用した処理に適しています)に変換するには、次のようにしますxml2
。
この動画は11チャプターで構成された約48分分の動画で、ほとんどの長さが約5分(300秒)です。
$ lsdvd -c -Ox '/path/to/some/dvd.iso' | xml2
/lsdvd/device=/path/to/some/dvd.iso
/lsdvd/title=TITLE
/lsdvd/vmg_id=DVDVIDEO-VMG
/lsdvd/provider_id=PROVIDER
/lsdvd/track/ix=1
/lsdvd/track/length=2874.667
/lsdvd/track/vts_id=DVDVIDEO-VTS
/lsdvd/track/chapter/ix=1
/lsdvd/track/chapter/length=299.934
/lsdvd/track/chapter/startcell=1
/lsdvd/track/chapter
/lsdvd/track/chapter/ix=2
/lsdvd/track/chapter/length=299.500
/lsdvd/track/chapter/startcell=2
/lsdvd/track/chapter
/lsdvd/track/chapter/ix=3
/lsdvd/track/chapter/length=300.000
/lsdvd/track/chapter/startcell=3
[...]
/lsdvd/track/chapter/ix=11
/lsdvd/track/chapter/length=176.734
/lsdvd/track/chapter/startcell=11
/lsdvd/longest_track=1
これはたくさん人間が読めるデフォルト出力よりもスクリプトで処理する方が簡単ですlsdvd
。たとえば、章の長さを秒単位で希望する場合:
$ lsdvd -c -Ox /path/to/some/dvd.iso' | xml2 | \
awk -F'[/=]' '$5 == "length" { print $6 }'
299.934
299.500
300.000
299.500
300.000
299.500
299.500
300.000
299.500
0.500
176.734
また、awkを使用するとgrepが不要であることを指摘したいと思います。したがって、人間が読める出力を使用するには、末尾のコンマを削除することで、grep | grep | awk
次のように減らすことができます。len=${len:0:12}
lsdvd -c VIDEO_TS | awk -F' +|,' '/Chapter:/ && /Length:/ { print $5 }' | \
while read len
フィールド区切り文字は、ここでは 1 つ以上のスペースまたはカンマで定義されます。
$ lsdvd -c '/path/to/some/dvd.iso' | \
awk -F' +|,' '/Chapter:/ && /Length:/ { print $5 }'
00:04:59.934
00:04:59.500
00:05:00.000
00:04:59.500
00:05:00.000
00:04:59.500
00:04:59.500
00:05:00.000
00:04:59.500
00:00:00.500
00:02:56.734