Overview: • About Miller • Miller in 10 minutes • File formats • Miller features in the context of the Unix toolkit • Record-heterogeneity • Internationalization Using Miller: • FAQ • Cookbook part 1 • Cookbook part 2 • Cookbook part 3 • Data-diving examples • Manpage • Reference • Reference: Verbs • Reference: DSL • Documents by release • Installation, portability, dependencies, and testing Background: • Why? • Why C? • Why call it Miller? • How original is Miller? • Performance Repository: • Things to do • Contact information • GitHub repo |
• Randomly generating jabberwocky words • Program timing • Computing interquartile ranges • Computing weighted means • Generating random numbers from various distributions • Sieve of Eratosthenes • Mandelbrot-set generator Randomly selecting words from a list
Given this word list, first take a
look to see what the first few lines look like:
$ head data/english-words.txt a aa aal aalii aam aardvark aardwolf aba abac abaca $ mlr --from data/english-words.txt --nidx filter 'n=strlen($1);4<=n&&n<=8' then sample -k 10 thionine birchman mildewy avigate addedly abaze askant aiming insulant coinmate Randomly generating jabberwocky words
These are simple n-grams as described
here. Some common functions are
here.
Then here are scripts for
1-grams,
2-grams,
3-grams,
4-grams, and
5-grams.
The idea is that words from the input file are consumed, then taken apart and pasted back together
in ways which imitate the letter-to-letter transitions found in the word list — giving us automatically
generated words in the same vein as bromance and spork:
$ mlr --nidx --from ./ngrams/gsl-2000.txt put -q -f ./ngrams/ngfuncs.mlr -f ./ngrams/ng5.mlr beard plastinguish politicially noise loan country controductionary suppery lose lessors dollar judge rottendence lessenger diffendant suggestional Program timing
This admittedly artificial example demonstrates using Miller time and stats
functions to introspectively acquire some information about Miller’s own
runtime. The delta function computes the difference between successive
timestamps.
$ ruby -e '10000.times{|i|puts "i=#{i+1}"}' > lines.txt $ head -n 5 lines.txt i=1 i=2 i=3 i=4 i=5 mlr --ofmt '%.9le' --opprint put '$t=systime()' then step -a delta -f t lines.txt | head -n 7 i t t_delta 1 1430603027.018016 1.430603027e+09 2 1430603027.018043 2.694129944e-05 3 1430603027.018048 5.006790161e-06 4 1430603027.018052 4.053115845e-06 5 1430603027.018055 2.861022949e-06 6 1430603027.018058 3.099441528e-06 mlr --ofmt '%.9le' --oxtab \ put '$t=systime()' then \ step -a delta -f t then \ filter '$i>1' then \ stats1 -a min,mean,max -f t_delta \ lines.txt t_delta_min 2.861022949e-06 t_delta_mean 4.077508505e-06 t_delta_max 5.388259888e-05 Computing interquartile rangesFor one or more specified field names, simply compute p25 and p75, then write the IQR as the difference of p75 and p25: $ mlr --oxtab stats1 -f x -a p25,p75 \ then put '$x_iqr = $x_p75 - $x_p25' \ data/medium x_p25 0.246670 x_p75 0.748186 x_iqr 0.501516 For wildcarded field names, first compute p25 and p75, then loop over field names with p25 in them: $ mlr --oxtab stats1 --fr '[i-z]' -a p25,p75 \ then put 'for (k,v in $*) { if (k =~ "(.*)_p25") { $["\1_iqr"] = $["\1_p75"] - $["\1_p25"] } }' \ data/medium i_p25 2501 i_p75 7501 x_p25 0.246670 x_p75 0.748186 y_p25 0.252137 y_p75 0.764003 i_iqr 5000 x_iqr 0.501516 y_iqr 0.511866 Computing weighted meansThis might be more elegantly implemented as an option within the stats1 verb. Meanwhile, it’s expressible within the DSL: $ mlr --from data/medium put -q ' # Using the y field for weighting in this example weight = $y; # Using the a field for weighted aggregation in this example @sumwx[$a] += weight * $i; @sumw[$a] += weight; @sumx[$a] += $i; @sumn[$a] += 1; end { map wmean = {}; map mean = {}; for (a in @sumwx) { wmean[a] = @sumwx[a] / @sumw[a] } for (a in @sumx) { mean[a] = @sumx[a] / @sumn[a] } #emit wmean, "a"; #emit mean, "a"; emit (wmean, mean), "a"; }' a=pan,wmean=4979.563722,mean=5028.259010 a=eks,wmean=4890.381593,mean=4956.290076 a=wye,wmean=4946.987746,mean=4920.001017 a=zee,wmean=5164.719685,mean=5123.092330 a=hat,wmean=4925.533162,mean=4967.743946 Generating random numbers from various distributions
Here we can chain together a few simple building blocks:
$ cat expo-sample.sh # Generate 100,000 pairs of independent and identically distributed # exponentially distributed random variables with the same rate parameter # (namely, 2.5). Then compute histograms of one of them, along with # histograms for their sum and their product. # # See also https://en.wikipedia.org/wiki/Exponential_distribution # # Here I'm using a specified random-number seed so this example always # produces the same output for this web document: in everyday practice we # wouldn't do that. mlr -n \ --seed 0.25 \ --opprint \ seqgen --stop 100000 \ then put ' # https://en.wikipedia.org/wiki/Inverse_transform_sampling func expo_sample(lambda) { return -log(1-urand())/lambda } $u = expo_sample(2.5); $v = expo_sample(2.5); $s = $u + $v; $p = $u * $v; ' \ then histogram -f u,s,p --lo 0 --hi 2 --nbins 50 \ then bar -f u_count,s_count,p_count --auto -w 20
$ sh expo-sample.sh bin_lo bin_hi u_count s_count p_count 0.000000 0.040000 [78]*******************#[9497] [353]#...................[3732] [20]*******************#[39755] 0.040000 0.080000 [78]******************..[9497] [353]*****...............[3732] [20]*******.............[39755] 0.080000 0.120000 [78]****************....[9497] [353]*********...........[3732] [20]****................[39755] 0.120000 0.160000 [78]**************......[9497] [353]************........[3732] [20]***.................[39755] 0.160000 0.200000 [78]*************.......[9497] [353]**************......[3732] [20]**..................[39755] 0.200000 0.240000 [78]************........[9497] [353]****************....[3732] [20]*...................[39755] 0.240000 0.280000 [78]**********..........[9497] [353]******************..[3732] [20]*...................[39755] 0.280000 0.320000 [78]**********..........[9497] [353]******************..[3732] [20]*...................[39755] 0.320000 0.360000 [78]*********...........[9497] [353]*******************.[3732] [20]#...................[39755] 0.360000 0.400000 [78]********............[9497] [353]*******************.[3732] [20]#...................[39755] 0.400000 0.440000 [78]*******.............[9497] [353]*******************#[3732] [20]#...................[39755] 0.440000 0.480000 [78]******..............[9497] [353]******************..[3732] [20]#...................[39755] 0.480000 0.520000 [78]*****...............[9497] [353]******************..[3732] [20]#...................[39755] 0.520000 0.560000 [78]*****...............[9497] [353]******************..[3732] [20]#...................[39755] 0.560000 0.600000 [78]****................[9497] [353]*****************...[3732] [20]#...................[39755] 0.600000 0.640000 [78]****................[9497] [353]*****************...[3732] [20]#...................[39755] 0.640000 0.680000 [78]****................[9497] [353]****************....[3732] [20]#...................[39755] 0.680000 0.720000 [78]***.................[9497] [353]****************....[3732] [20]#...................[39755] 0.720000 0.760000 [78]***.................[9497] [353]**************......[3732] [20]#...................[39755] 0.760000 0.800000 [78]**..................[9497] [353]**************......[3732] [20]#...................[39755] 0.800000 0.840000 [78]**..................[9497] [353]*************.......[3732] [20]#...................[39755] 0.840000 0.880000 [78]**..................[9497] [353]************........[3732] [20]#...................[39755] 0.880000 0.920000 [78]**..................[9497] [353]***********.........[3732] [20]#...................[39755] 0.920000 0.960000 [78]*...................[9497] [353]***********.........[3732] [20]#...................[39755] 0.960000 1.000000 [78]*...................[9497] [353]**********..........[3732] [20]#...................[39755] 1.000000 1.040000 [78]*...................[9497] [353]*********...........[3732] [20]#...................[39755] 1.040000 1.080000 [78]*...................[9497] [353]*********...........[3732] [20]#...................[39755] 1.080000 1.120000 [78]*...................[9497] [353]********............[3732] [20]#...................[39755] 1.120000 1.160000 [78]*...................[9497] [353]********............[3732] [20]#...................[39755] 1.160000 1.200000 [78]#...................[9497] [353]*******.............[3732] [20]#...................[39755] 1.200000 1.240000 [78]#...................[9497] [353]******..............[3732] [20]#...................[39755] 1.240000 1.280000 [78]#...................[9497] [353]*****...............[3732] [20]#...................[39755] 1.280000 1.320000 [78]#...................[9497] [353]*****...............[3732] [20]#...................[39755] 1.320000 1.360000 [78]#...................[9497] [353]*****...............[3732] [20]#...................[39755] 1.360000 1.400000 [78]#...................[9497] [353]****................[3732] [20]#...................[39755] 1.400000 1.440000 [78]#...................[9497] [353]****................[3732] [20]#...................[39755] 1.440000 1.480000 [78]#...................[9497] [353]***.................[3732] [20]#...................[39755] 1.480000 1.520000 [78]#...................[9497] [353]***.................[3732] [20]#...................[39755] 1.520000 1.560000 [78]#...................[9497] [353]***.................[3732] [20]#...................[39755] 1.560000 1.600000 [78]#...................[9497] [353]**..................[3732] [20]#...................[39755] 1.600000 1.640000 [78]#...................[9497] [353]**..................[3732] [20]#...................[39755] 1.640000 1.680000 [78]#...................[9497] [353]*...................[3732] [20]#...................[39755] 1.680000 1.720000 [78]#...................[9497] [353]*...................[3732] [20]#...................[39755] 1.720000 1.760000 [78]#...................[9497] [353]*...................[3732] [20]#...................[39755] 1.760000 1.800000 [78]#...................[9497] [353]*...................[3732] [20]#...................[39755] 1.800000 1.840000 [78]#...................[9497] [353]#...................[3732] [20]#...................[39755] 1.840000 1.880000 [78]#...................[9497] [353]#...................[3732] [20]#...................[39755] 1.880000 1.920000 [78]#...................[9497] [353]#...................[3732] [20]#...................[39755] 1.920000 1.960000 [78]#...................[9497] [353]#...................[3732] [20]#...................[39755] 1.960000 2.000000 [78]#...................[9497] [353]#...................[3732] [20]#...................[39755] Sieve of Eratosthenes
The Sieve_of_Eratosthenes
is a standard introductory programming topic. The idea is to find all primes up
to some N by making a list of the numbers 1 to N, then striking
out all multiples of 2 except 2 itself, all multiples of 3 except 3 itself, all
multiples of 4 except 4 itself, and so on. Whatever survives that without
getting marked is a prime. This is easy enough in Miller. Notice that here all
the work is in begin and end statements; there is no file
input (so we use mlr -n to keep Miller from waiting for input data).
$ cat programs/sieve.mlr # ================================================================ # Sieve of Eratosthenes: simple example of Miller DSL as programming language. # ================================================================ # Put this in a begin-block so we can do either # mlr -n put -q -f name-of-this-file.mlr # or # mlr -n put -q -f name-of-this-file.mlr -e '@n = 200' # i.e. 100 is the default upper limit, and another can be specified using -e. begin { @n = 100; } end { for (int i = 0; i <= @n; i += 1) { @s[i] = true; } @s[0] = false; # 0 is neither prime nor composite @s[1] = false; # 1 is neither prime nor composite # Strike out multiples for (int i = 2; i <= @n; i += 1) { for (int j = i+i; j <= @n; j += i) { @s[j] = false; } } # Print survivors for (int i = 0; i <= @n; i += 1) { if (@s[i]) { print i; } } } $ mlr -n put -f programs/sieve.mlr 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 Mandelbrot-set generator
The Mandelbrot
set is also easily expressed. This isn’t an important case of
data-processing in the vein for which Miller was designed, but it is an
example of Miller as a general-purpose programming language — a test
case for the expressiveness of the language.
The (approximate) computation of points in the complex plane which are and
aren’t members is just a few lines of complex arithmetic (see the
Wikipedia article); how to render them is another task. Using graphics
libraries you can create PNG or JPEG files, but another fun way to do this is
by printing various characters to the screen:
$ cat programs/mand.mlr # Mandelbrot set generator: simple example of Miller DSL as programming language. begin { # Set defaults @rcorn = -2.0; @icorn = -2.0; @side = 4.0; @iheight = 50; @iwidth = 100; @maxits = 100; @levelstep = 5; @chars = "@X*o-."; # Palette of characters to print to the screen. @verbose = false; @do_julia = false; @jr = 0.0; # Real part of Julia point, if any @ji = 0.0; # Imaginary part of Julia point, if any } # Here, we can override defaults from an input file (if any). In Miller's # put/filter DSL, absent-null right-hand sides result in no assignment so we # can simply put @rcorn = $rcorn: if there is a field in the input like # 'rcorn = -1.847' we'll read and use it, else we'll keep the default. @rcorn = $rcorn; @icorn = $icorn; @side = $side; @iheight = $iheight; @iwidth = $iwidth; @maxits = $maxits; @levelstep = $levelstep; @chars = $chars; @verbose = $verbose; @do_julia = $do_julia; @jr = $jr; @ji = $ji; end { if (@verbose) { print "RCORN = ".@rcorn; print "ICORN = ".@icorn; print "SIDE = ".@side; print "IHEIGHT = ".@iheight; print "IWIDTH = ".@iwidth; print "MAXITS = ".@maxits; print "LEVELSTEP = ".@levelstep; print "CHARS = ".@chars; } # Iterate over a matrix of rows and columns, printing one character for each cell. for (int ii = @iheight-1; ii >= 0; ii -= 1) { num pi = @icorn + (ii/@iheight) * @side; for (int ir = 0; ir < @iwidth; ir += 1) { num pr = @rcorn + (ir/@iwidth) * @side; printn get_point_plot(pr, pi, @maxits, @do_julia, @jr, @ji); } print; } } # This is a function to approximate membership in the Mandelbrot set (or Julia # set for a given Julia point if do_julia == true) for a given point in the # complex plane. func get_point_plot(pr, pi, maxits, do_julia, jr, ji) { num zr = 0.0; num zi = 0.0; num cr = 0.0; num ci = 0.0; if (!do_julia) { zr = 0.0; zi = 0.0; cr = pr; ci = pi; } else { zr = pr; zi = pi; cr = jr; ci = ji; } int iti = 0; bool escaped = false; num zt = 0; for (iti = 0; iti < maxits; iti += 1) { num mag = zr*zr + zi+zi; if (mag > 4.0) { escaped = true; break; } # z := z^2 + c zt = zr*zr - zi*zi + cr; zi = 2*zr*zi + ci; zr = zt; } if (!escaped) { return "."; } else { # The // operator is Miller's (pythonic) integer-division operator int level = (iti // @levelstep) % strlen(@chars); return substr(@chars, level, level); } } $ mlr -n put -f ./programs/mand.mlr @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@XXXXXX@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@XXXX.XXXX@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@XXXXXXXooXXXX@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@XXXXX**o..*XXXXX@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@XXXXXX*-....-oXXXXXX@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@XXXXX@XXXXXXXXXX*......o*XXXXXXXXXX@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@XXXXXXXXXX**oo*-.-........oo.XXXXXXXXX@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@XXXXXXXXXXXXX....................X..o-XXX@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@XXXXXXXXXXXXXXX*oo......................oXXXXX@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@XXX*XXXXXXXXXXXX**o........................*X*X@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@XXXXXXooo***o*.*XX**X..........................o-XX@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@XXXXXXXX*-.......-***.............................oXX@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@XXXXXXXX*@..........Xo............................*XX@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@XXXX@XXXXXXXX*o@oX...........@...........................oXXX@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ .........................................................o*XXXXX@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@XXXXXXXXX*-.oX...........@...........................oXXXXX@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@XXXXXXXXXX**@..........*o............................*XXXXXXXX@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@XXXXXXXXXXXXX-........***.............................oXXXXXXXXXX@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@XXXXXXXXXXXXoo****o*.XX***@..........................o-XXXXXXXXXXXXX@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@XXXXX*XXXX*XXXXXXX**-........................***XXXXX@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@XXXXXXXXXXXXX*o*.....................@o*XXXX@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@XXXXXXXXXXXX*....................*..o-XX@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@XXXXX*ooo*-.o........oo.X*XXXXXX@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@XXXXXXXXX**@.....*XXXXXXXXX@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@XXXXXXXXX*o....-o*XXXXXX@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@XXXXXXXXXXo*o..*XXXXXXXX@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@XXXXXXXXXXXXX*o*XXXXXXX@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@XXXXXXXXXXXX@XXXXXXXX@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@XXXXXXXXX@@XXXXX@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@XXXXX@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #!/bin/bash # Get the number of rows and columns from the terminal window dimensions iheight=$(stty size | mlr --nidx --fs space cut -f 1) iwidth=$(stty size | mlr --nidx --fs space cut -f 2) echo "rcorn=-1.755350,icorn=+0.014230,side=0.000020,maxits=10000,iheight=$iheight,iwidth=$iwidth" \ | mlr put -f programs/mand.mlr |