我想要实现的是第1章开始时间和第2章开始时间之间的差异等等,从数组中的下一个开始减去每个章节的开始时间,例如00:05:57 - 00:01:03 = 00:04:54
$ cat ChapterStart
00:00:00 00:01:03 00:05:57 00:08:27 00:11:58 00:14:50 00:20:19 00:25:06 00:33:17 00:38:21 00:42:30 00:46:11 00:51:33 01:00:04 01:00:56 01:04:15 01:09:13 01:16:51 01:20:03 01:27:58
这根本不起作用:
#!/bin/bash
awk 'BEGIN{
{
for(i=1;i<=NF;i++){
m=split($i,t,":")
n=split($(i+1),w,":")
chap = (t[1]*3600) + (t[2]*60) + t[3]
chap_next = (w[1]*3600) + (w[2]*60) + w[3]
duration = (chap_next - chap)
print $duration
}
}
}'ChapterStart
有什么建议吗?
答案 0 :(得分:1)
问题是你在BEGIN
块中运行整个事情,所以它永远不会看到数据。只需删除“BEGIN {”和最后一个“}”,它就可以正常工作。
BEGIN
块在读取任何数据之前运行,并用于初始化。 awk程序结构如下所示(BEGIN
,主数据循环 - 由一个或多个块组成 - 而END
都是可选的):
BEGIN {
}
{
}
END {
}
主循环中的程序块可以有各种条件表达式,正则表达式或模式,用于选择是否执行它们。
此外,您的循环需要在最后一个字段之前停止,因为它无法在最后一个字段之后获取下一个字段:
for(i=1;i<NF;i++){
除非您删除美元符号,否则此行无效:
print $duration
由于你没有对split
的返回值做任何事情,你可以消除变量赋值或重用变量:
split($i,t,":")
split($(i+1),w,":")
或
m=split($i,t,":")
m=split($(i+1),w,":")
此外,当您发布问题“不起作用”时,信息量不大。
答案 1 :(得分:0)
正确的代码应该是
awk '{
for(i=1;i<NF;i++){
m=split($i,t,":")
n=split($(i+1),w,":")
chap = (t[1]*3600) + (t[2]*60) + t[3]
chap_next = (w[1]*3600) + (w[2]*60) + w[3]
duration = (chap_next - chap)
print duration
}
}' file
在awk读取输入文件之前处理BEGIN块。因此,如果将代码放在BEGIN块中,则不会处理该文件。
答案 2 :(得分:0)
此外,当您发布问题时 “不起作用”的信息量不大。
你当然是对的。也许最好是说“什么都不做”本来就很准确,因为什么都没发生。 =)
感谢你们两位。
虽然我还没有完全理解awk的许多神秘方式,但我确实找到了一个更简单(对我而言)的解决方案,并在此过程中学到了很多东西。这可行,但肯定可以做得更好。
#!/bin/bash
#~ Prelude to a DVD audio ripper.
#~ This simply prints Audio ID's & start/end/duration times for the longest DVD title.
MPLAYER=$(which mplayer)
DRIVE=${1:-/dev/dvd} ## Check for softlink to DVD drive, otherwise let user specify
if ! [ -b "$DRIVE" ]; then
read -p "DVD drive name? (/dev/scd0 for example): " DRIVE
fi
#~ Find, then scan the longest title
LTITLE=$($MPLAYER dvd:// -dvd-device $DRIVE -identify -vo null -ao null -nolirc -nojoystick \
-frames 0 2>/dev/null| awk '/ID_DVD_TITLE/'|awk '/LENGTH/'|sort -n -t = -k 2 |tail -1 |cut -f 4 -d _)
MPLAYER_OUT=$($MPLAYER dvd://$LTITLE -dvd-device $DRIVE -identify -vo null -ao null -nolirc \
-nojoystick -frames 0 2>/dev/null) ## mplayer tells us about the longest title on the disc/image
#~ Set some variables per $MPLAYER_OUT
VID=$(echo "$MPLAYER_OUT"|awk '/ID_DVD_VOLUME_ID=/{sub(/ID_DVD_VOLUME_ID=/,"");print}') ## Get the DVD Volume ID
CHAPTERS=$(echo "$MPLAYER_OUT"|awk '/ID_CHAPTERS/ {sub(/ID_CHAPTERS=/,"");print}') ## Total number of chapters in longest title
ChapStart=($(echo "$MPLAYER_OUT"|awk '/CHAPTERS:/'|sed 's/CHAPTERS://; s/,/\n /g'))
ChapEnd=($(echo "$MPLAYER_OUT"|awk '/CHAPTERS:/'|sed 's/CHAPTERS://; s/,/\n /g'))
DiscTimeTotal=$(echo "$MPLAYER_OUT" |awk '/ID_DVD_TITLE_'$LTITLE'_LENGTH/ {sub(/ID_DVD_TITLE_'$LTITLE'_LENGTH=/,"");print}')
DiscTime=$(echo "$MPLAYER_OUT" |echo - |awk '{printf "%02d:%02d:%02d","'"$DiscTimeTotal"'"/(60*60),"'"$DiscTimeTotal"'"%(60*60)/60,"'"$DiscTimeTotal"'"%60}';echo) ## Converted to HH:MM:SS
Disc=$(date +%s -d "$DiscTime") ## Convert to seconds since 1970-01-01 - this becomes that last ChapTimeEnd array element
Streams=$(echo "$MPLAYER_OUT" |awk '/audio stream/'|sed 's/.$//;s/language/Language/'|awk '{ print "AID: " $10, "Format: " $5, $7, $8, $6 }')
#~ Convert ChapStart HH:MM:SS to ChapTimeStart seconds since 1970-01-01
for ((s=0; s<=$CHAPTERS; s++))
do
ChapTimeStart[$s]=$(date +%s -d "${ChapStart[$s]}")
ChapTimeEnd[$s]=$(date +%s -d "${ChapEnd[$s]}")
done
unset ChapTimeEnd[0] ## Remove the first chapter start time (always 00:00:00) in the array
ChapTimeEnd[$CHAPTERS]=$Disc ## Add $Disc as last array element
ChapTimeEnd=( "${ChapTimeEnd[@]}" ) ## Pack the array
unset ChapEnd[0] ## Offset the time differences - this is printed to screen as "End: HH:MM:SS"
ChapEnd[$CHAPTERS]=$DiscTime ## Add $DiscTime as last array element
ChapEnd=( "${ChapEnd[@]}" ) ## Pack the array
#~ Provide some feedback:
echo
echo " --- DVD Volume ID ---";echo
echo "$VID";echo
echo " --- Longest Title ----";echo
echo "Title $LTITLE is longest with $CHAPTERS Chapters"
echo "Title $LTITLE Length: $DiscTime";echo
echo " ---- Audio ID's ----";echo
echo "$Streams";echo
#~ Print start/end/duration
echo " ---- Chapters ----";echo
for ((t=0; t<$CHAPTERS; t++))
do TimeDiff[$t]=$((${ChapTimeEnd[$t]} - ${ChapTimeStart[$t]})) ## Do the integer math with values expressed as seconds since 1970-01-01
Duration=$(echo - |awk '{printf "%02d:%02d:%02d","'"${TimeDiff[$t]}"'"/(60*60),"'"${TimeDiff[$t]}"'"%(60*60)/60,"'"${TimeDiff[$t]}"'"%60}';echo)
echo "Chapter: `printf "%02d" $(($t+1))` Start: "${ChapStart[$t]}" End: "${ChapEnd[$t]}" Duration: $Duration"
done
echo "_____________________________________________________________"
echo