Test results so far with the following file
Code: Select all
/root/file1.mp3| 1345641102,1345644563,1345647584,1345647585,1345647586,1345647587,1345647588,1345647589,1345647590,1345740286,1345740287,1345740288,1345740290,1345740291,1345740291,1345740292,1345740293,1345740293,1345740294,1345740295,1345740296,1345740297,1345740298,1345740299,1345740300
/root/file2.mp3| 1345623045,1345643786,1345648695,1345648696,1345648697,1345648698,1345648699,1345648700,1345648701,1345740286,1345740287,1345740288,1345740290,1345740291,1345740291,1345740292,1345740293,1345740293,1345740294,1345740295,1345740296,1345740297,1345740298,1345740299,1345740300
[...]
/root/file1999.mp3| 1345641102,1345644563,1345647584,1345647585,1345647586,1345647587,1345647588,1345647589,1345647590,1345740286,1345740287,1345740288,1345740290,1345740291,1345740291,1345740292,1345740293,1345740293,1345740294,1345740295,1345740296,1345740297,1345740298,1345740299,1345740300
/root/file2000øæå.mp3| 1345623045,1345643786,1345648695,1345648696,1345648697,1345648698,1345648699,1345648700,1345648701,1345740286,1345740287,1345740288,1345740290,1345740291,1345740291,1345740292,1345740293,1345740293,1345740294,1345740295,1345740296,1345740297,1345740298,1345740299,1345740300
########################################
Code: Select all
#!/bin/bash
#usage: played_since_foreach time
time="$1";
ifs_bak="$IFS"
IFS=""
while read -d "|" record; do
IFS=","
#Get all timestamps in array
read -a times
#Binary search
i=$(( ${#times[*]}/2 ))
d=$(( $i/2 ))
test "$d" -eq "0" && d=1 #precaution
ulim=$(( ${#times[*]}-1 ))
count=-1
while test "$i" -ge "0" -a "$i" -lt "$ulim"; do #check whether index is in range
if test "$time" -lt "${times[$i]}"; then
i=$(( $i-$d ))
elif test "$time" -gt "${times[$(( $i+1 ))]}"; then
i=$(( $i+$d ))
else
#found, tell no. of records greater than this
count="$(( $ulim-$i ))"
break
fi
d=$(( ($d/2) ))
test "$d" -eq "0" && d=1 #precaution
done
#In case of 'out of range'
if test "$count" -lt "0"; then
if test "$ulim" -lt "0"; then
count=0
else
if test "$time" -lt "$times"; then
count="${#times[*]}"
elif test "$time" -gt "${times[$ulim]}"; then
count=0
else
count="bug" #This should not be reached
fi
fi
fi
#Show result for this record
echo "$record: $count"
done < database.txt
IFS="$ifs_bak"
Code: Select all
real 0m1.129s
user 0m1.080s
sys 0m0.047s
########################################
Code: Select all
#!/bin/ash
timestamp=$1
ifs_bak=$IFS
IFS=","
while read LOGENTRY; do
filename=${LOGENTRY%%|*}
#LOGENTRY=`grep $filename database.txt`
#grep is faster than while read case on large files
STAMPS=${LOGENTRY#*|}
#you could use bash arrays instead - set allows "arrays" in sh, ash, etc...
#set ${STAMPS//,/ }
set ${STAMPS}
#for speed change IFS to "," vs. the //,/ } but don't forget to reset it
while ( [ $1 ] && [ $1 -lt $timestamp ]) do
shift #a hacky way to remove all entries < timestamp
done
# $# is the number of args passed or in this case set with "set ..."
echo The number of times played $filename since $timestamp is $#
done < database.txt
IFS=$ifs_bak
Code: Select all
real 0m1.434s
user 0m0.190s
sys 0m0.633s
########################################
Code: Select all
#!/bin/ash
LANG=C
FIND=$1
cat /root/database.txt |
awk -F, -v TS=$FIND '{
split($1, a, "|"); $1=a[2] # fix first entry
max=NF; min=1;
while (max-min > 1) {
i=int( (max+min)/2 )
if (TS >= $i) min = i
else max = i
}
print a[1], NF-min
}'
Code: Select all
real 0m0.026s
user 0m0.020s
sys 0m0.003s
########################################
All worked with non-english filename /root/file2000øæå.mp3
Thank you all
Sigmund