Вычитание времени с AWK - PullRequest
       6

Вычитание времени с AWK

0 голосов
/ 11 января 2010

Я пытаюсь достичь разницы между временем начала главы 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

Есть предложения?

Ответы [ 3 ]

1 голос
/ 11 января 2010

Проблема в том, что вы запускаете все это в блоке 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,":")

Кроме того, когда вы отправляете вопрос «не работает», он не очень информативен.

0 голосов
/ 23 февраля 2010

Также, когда вы отправляете вопрос «не работает» не очень информативно.

Вы, конечно, правы. Возможно, было бы предпочтительнее сказать «ничего не делает», что было бы совершенно точно, потому что ничего не произошло. =)

Спасибо вам обоим.

Хотя я еще не до конца понял многие загадочные способы 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
0 голосов
/ 11 января 2010

правильный код должен быть

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

Блок BEGIN обрабатывается до того, как awk прочитает входной файл. Поэтому, если вы поместите свой код в блок BEGIN, файл не будет обработан.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...