binsearch: Supports -q and -2.
This commit is contained in:
parent
4206374f37
commit
b29b851281
|
@ -19,16 +19,57 @@ B<binsearch> runs I<command> with a single number. It returns highest
|
||||||
value that I<command> succeeds for.
|
value that I<command> succeeds for.
|
||||||
|
|
||||||
|
|
||||||
|
=head1 OPTIONS
|
||||||
|
|
||||||
|
=over 4
|
||||||
|
|
||||||
|
=item B<-2>
|
||||||
|
|
||||||
|
Instead of the command a single argument, give the command 2 argument:
|
||||||
|
I<from> I<to>.
|
||||||
|
|
||||||
|
=item B<-q>
|
||||||
|
|
||||||
|
Quiet. Ignore output from B<command>.
|
||||||
|
|
||||||
|
|
||||||
|
=back
|
||||||
|
|
||||||
|
|
||||||
=head1 EXAMPLES
|
=head1 EXAMPLES
|
||||||
|
|
||||||
|
=head2 Find the last file
|
||||||
|
|
||||||
|
This is a silly way to find the last non-existing file (namely 244):
|
||||||
|
|
||||||
|
touch {245..800}
|
||||||
|
binsearch ls
|
||||||
|
|
||||||
|
This is a silly way to find the last file (namely 800):
|
||||||
|
|
||||||
|
touch {1..800}
|
||||||
|
binsearch ls
|
||||||
|
|
||||||
=head2 Test a bash function
|
=head2 Test a bash function
|
||||||
|
|
||||||
|
Test how long an argument /bin/echo can take
|
||||||
|
|
||||||
. $(which binsearch)
|
. $(which binsearch)
|
||||||
singleecho() {
|
singleecho() {
|
||||||
/bin/echo $(perl -e 'print "x"x'$1) >/dev/null
|
/bin/echo $(perl -e 'print "x"x'$1) >/dev/null
|
||||||
}
|
}
|
||||||
binsearch singleecho
|
binsearch singleecho
|
||||||
|
|
||||||
|
=head2 Test a bash function that takes from and to as arguments
|
||||||
|
|
||||||
|
Use a function that takes two arguments
|
||||||
|
|
||||||
|
. $(which binsearch)
|
||||||
|
greplines() {
|
||||||
|
env | perl -ne "$1..$2 and print" | grep HOME=
|
||||||
|
}
|
||||||
|
binsearch -2 -q greplines
|
||||||
|
|
||||||
|
|
||||||
=head1 AUTHOR
|
=head1 AUTHOR
|
||||||
|
|
||||||
|
@ -60,19 +101,6 @@ B<eval>(1)
|
||||||
|
|
||||||
=cut
|
=cut
|
||||||
|
|
||||||
|
|
||||||
# Example: find the max line length
|
|
||||||
#
|
|
||||||
# singleecho() {
|
|
||||||
# /bin/echo $(perl -e 'print "x"x'$1) >/dev/null
|
|
||||||
# }
|
|
||||||
#
|
|
||||||
# multiecho() {
|
|
||||||
# /bin/echo $(perl -e 'print "x "x'$(($1/2)) ) >/dev/null
|
|
||||||
# }
|
|
||||||
#
|
|
||||||
# binsearch singleecho
|
|
||||||
|
|
||||||
binsearch() {
|
binsearch() {
|
||||||
_binsearch() {
|
_binsearch() {
|
||||||
low=$1
|
low=$1
|
||||||
|
@ -84,7 +112,7 @@ binsearch() {
|
||||||
shift
|
shift
|
||||||
shift
|
shift
|
||||||
middle=$(( ( $low + $high ) / 2 ))
|
middle=$(( ( $low + $high ) / 2 ))
|
||||||
if eval "$@ $middle" ; then
|
if _run $low $middle "$@" ; then
|
||||||
low=$middle
|
low=$middle
|
||||||
else
|
else
|
||||||
high=$middle
|
high=$middle
|
||||||
|
@ -92,9 +120,35 @@ binsearch() {
|
||||||
_binsearch $low $high "$@"
|
_binsearch $low $high "$@"
|
||||||
}
|
}
|
||||||
|
|
||||||
low=1
|
_run() {
|
||||||
|
local a="$1"
|
||||||
|
local b="$2"
|
||||||
|
shift
|
||||||
|
shift
|
||||||
|
# echo "a=$a b=$b $@"
|
||||||
|
if $opt2 ; then
|
||||||
|
eval "$not" "$@ $a $b" "$quiet"
|
||||||
|
else
|
||||||
|
eval "$not" "$@ $b" "$quiet"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
quiet=""
|
||||||
|
opt2=false
|
||||||
|
args=$(getopt 'q2' $*) || exit
|
||||||
|
# now we have the sanitized args... replace the original with it
|
||||||
|
set -- $args
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
case $1 in
|
||||||
|
(-2) opt2=true; shift;;
|
||||||
|
(-q) quiet=">/dev/null 2>/dev/null"; shift;;
|
||||||
|
(--) shift; break;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
# If function(1) = false: run 'not function()' instead
|
# If function(1) = false: run 'not function()' instead
|
||||||
if eval "$@ $low" ; then
|
if _run 1 1 "$@" ; then
|
||||||
not=''
|
not=''
|
||||||
else
|
else
|
||||||
not='!'
|
not='!'
|
||||||
|
@ -102,17 +156,21 @@ binsearch() {
|
||||||
# exponential search for the first value that is false
|
# exponential search for the first value that is false
|
||||||
# low = previous value (function($low) == true)
|
# low = previous value (function($low) == true)
|
||||||
# high = low * 2 (function($high) == false)
|
# high = low * 2 (function($high) == false)
|
||||||
high=$low
|
high=1
|
||||||
while eval "$not" "$@ $high" 2>/dev/null ; do
|
while _run 1 $high "$@" ; do
|
||||||
low=$high
|
low=$high
|
||||||
high=$(( $high*2 ))
|
high=$(( $high*2 ))
|
||||||
|
if [ $high -gt 4611686018427387900 ] ; then
|
||||||
|
echo "$0: Error: exit value does not change of '$@'" >&2
|
||||||
|
return
|
||||||
|
fi
|
||||||
done
|
done
|
||||||
# echo "low: $low high: $high not: $not"
|
# echo "low: $low high: $high not: $not"
|
||||||
_binsearch $low $high "$not $@" 2>/dev/null
|
_binsearch $low $high "$@" 2>/dev/null
|
||||||
echo $low
|
echo $low
|
||||||
}
|
}
|
||||||
|
|
||||||
if [ -z "$@" ] ; then
|
if [ -z "$*" ] ; then
|
||||||
# source the bash function
|
# source the bash function
|
||||||
# . $(which binsearch)
|
# . $(which binsearch)
|
||||||
true
|
true
|
||||||
|
|
|
@ -9,7 +9,7 @@ splitvideo - Split video at time stamp
|
||||||
|
|
||||||
=head1 SYNOPSIS
|
=head1 SYNOPSIS
|
||||||
|
|
||||||
B<splitvideo> time videofile
|
B<splitvideo> I<time> I<videofile>
|
||||||
|
|
||||||
|
|
||||||
=head1 DESCRIPTION
|
=head1 DESCRIPTION
|
||||||
|
|
Loading…
Reference in a new issue