###################################################################### # comments and trailing commas in pseudo-JSON don't bother jeff jf -a . tsconfig.json compilerOptions target es5 module commonjs strict true esModuleInterop true skipLibCheck true forceConsistentCasingInFileNames true jf -to=lines 'in.tstype()' tsconfig.json interface { compilerOptions: interface { target: string module: string strict: boolean esModuleInterop: boolean skipLibCheck: boolean forceConsistentCasingInFileNames: boolean } } jf -from=ini -a in@tryparse Cargo.toml package name demos version 0.1.0 authors 1 items pac <none.of@your.biz> edition 2,018 dependencies {} # multiple inputs are put together into a general input object jf -a 'in.revalue(v.@limit20)' tsconfig.json https://www.google.com | head -n 30 tsconfig.json compilerOptions target es5 module commonjs strict true esModuleInterop true skipLibCheck true forceConsistentCasingInFileNames true https://www.google.com head @ head children 1 items @ meta @content text/html; charset=U @http-equiv Content-Type children 2 items @ meta @content /images/branding/goo @itemprop image children 5 items @ title text 1 items Google ········································ @ script @nonce s4I9Zm5bEcnaeeD6FPkw text 1 items (function(){var _g={ ········································ @ style # no need to pipe from curl and lose MIME-type autodetection # jf -a 'in . del(`client_ip`, `timezone`)[1:]' https://worldtimeapi.org/api/ip # the above is commented, not to risk showing ip and other info ###################################################################### # a text file with a million and 2 bytes of ASCII wc -cl e-digits.txt | nn 0 1000002 e-digits.txt # just showing the beginning of that single-line file head -c 52 e-digits.txt | nn 2.71828182845904523536028747135266249775724709369995 # tally all those digits jf -a in.tally e-digits.txt 2 99,846 . 1 7 99,910 1 100,132 8 99,814 4 100,389 5 100,087 9 99,691 0 99,425 3 100,228 6 100,479 jf -a 'in.tally.sort(-v)' e-digits.txt 6 100,479 4 100,389 3 100,228 1 100,132 5 100,087 7 99,910 2 99,846 8 99,814 9 99,691 0 99,425 . 1 # now these bullets are good for something: casual insta-glance on # the side conveys each digit key jf -a 'in.tally.sort(-v) . ren(`${k} ${+k*bullet}`)' e-digits.txt 6 •••••• 100,479 4 •••• 100,389 3 ••• 100,228 1 • 100,132 5 ••••• 100,087 7 ••••••• 99,910 2 •• 99,846 8 •••••••• 99,814 9 ••••••••• 99,691 0 99,425 . 1 ###################################################################### # colored tiles, showing numeric color scale overall jf -q '(0..50) . map((v/50).tile) . join . quote(nan.tile)' ×■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■× # simpler way to do the same jf -q '0..50.tiles . quote(nan.tile)' ×■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■× # some data stats/viz jf -q ' data = 50.map(rexp(3)) - 3; { stats: data.numstats, viz: data.spark, }' stats n 50 min -2.9943585613012100 max 10.875763491839111 sum 9.95385072507803 mean 0.1990770145015605 sd 3.732687119970095 geomean NaN rms 26.39408374578538 pos 20 zero 0 neg 30 nan 0 viz +▄▁▆▆█▆▇−▆−▂▆▆▇+▆▇▆▁▆+▆▆▇−▄▁▆−−▇+▇▆++▆▇▆+▇−▃▇▇▆+▇█ ###################################################################### # how many items each top-level item has jf -a '{k: v.len(): in}' cadex.json.gz groupDetail 3 terms 1 seriesDetail 26 observations 164 # what type each top-level item is, and how many items it has jf -a 'in.map({type: v.type(), items: v.len()})' cadex.json.gz groupDetail type object items 3 terms type object items 1 seriesDetail type object items 26 observations type array items 164 # what type each top-level item is, and how many items it has jf -a '{k: {type: v.type(), items: v.len()}: in}' cadex.json.gz groupDetail type object items 3 terms type object items 1 seriesDetail type object items 26 observations type array items 164 jf -to=lines 'in.tstype()' cadex.json.gz interface { groupDetail: interface { label: string description: string link: null } terms: interface { url: string } seriesDetail: interface { FXAUDCAD: interface { label: string description: string dimension: interface { key: string name: string } } FXBRLCAD: interface { label: string description: string dimension: interface { key: string name: string } } FXCNYCAD: interface { label: string description: string dimension: interface { key: string name: string } } FXEURCAD: interface { label: string description: string dimension: interface { key: string name: string } } FXHKDCAD: interface { label: string description: string dimension: interface { key: string name: string } } FXINRCAD: interface { label: string description: string dimension: interface { key: string name: string } } FXIDRCAD: interface { label: string description: string dimension: interface { key: string name: string } } FXJPYCAD: interface { label: string description: string dimension: interface { key: string name: string } } FXMYRCAD: interface { label: string description: string dimension: interface { key: string name: string } } FXMXNCAD: interface { label: string description: string dimension: interface { key: string name: string } } FXNZDCAD: interface { label: string description: string dimension: interface { key: string name: string } } FXNOKCAD: interface { label: string description: string dimension: interface { key: string name: string } } FXPENCAD: interface { label: string description: string dimension: interface { key: string name: string } } FXRUBCAD: interface { label: string description: string dimension: interface { key: string name: string } } FXSARCAD: interface { label: string description: string dimension: interface { key: string name: string } } FXSGDCAD: interface { label: string description: string dimension: interface { key: string name: string } } FXZARCAD: interface { label: string description: string dimension: interface { key: string name: string } } FXKRWCAD: interface { label: string description: string dimension: interface { key: string name: string } } FXSEKCAD: interface { label: string description: string dimension: interface { key: string name: string } } FXCHFCAD: interface { label: string description: string dimension: interface { key: string name: string } } FXTWDCAD: interface { label: string description: string dimension: interface { key: string name: string } } FXTHBCAD: interface { label: string description: string dimension: interface { key: string name: string } } FXTRYCAD: interface { label: string description: string dimension: interface { key: string name: string } } FXGBPCAD: interface { label: string description: string dimension: interface { key: string name: string } } FXUSDCAD: interface { label: string description: string dimension: interface { key: string name: string } } FXVNDCAD: interface { label: string description: string dimension: interface { key: string name: string } } } observations: []interface { d: string, FXAUDCAD: interface { v: string }, FXBRLCAD: interface { v: string }, FXCNYCAD: interface { v: string }, FXEURCAD: interface { v: string }, FXHKDCAD: interface { v: string }, FXINRCAD: interface { v: string }, FXIDRCAD: interface { v: string }, FXJPYCAD: interface { v: string }, FXMXNCAD: interface { v: string }, FXNZDCAD: interface { v: string }, FXNOKCAD: interface { v: string }, FXPENCAD: interface { v: string }, FXRUBCAD: interface { v: string }, FXSARCAD: interface { v: string }, FXSGDCAD: interface { v: string }, FXZARCAD: interface { v: string }, FXKRWCAD: interface { v: string }, FXSEKCAD: interface { v: string }, FXCHFCAD: interface { v: string }, FXTWDCAD: interface { v: string }, FXTRYCAD: interface { v: string }, FXGBPCAD: interface { v: string }, FXUSDCAD: interface { v: string } } } # typical example of a mid-complexity ad-hoc query, using gzipped data jf -a ' latest = in.observations.last; rates = {k-`FX`-`CAD`: +v.v: latest.drop(`d`)}; { date: latest.d, rates.sort(k)... }' cadex.json.gz | sbs 3 date 2023-08-25 █ IDR 0.000089 █ RUB 0.01428 AUD 0.8725000000000001 █ INR 0.01646 █ SAR 0.3627 BRL 0.2791 █ JPY 0.0093 █ SEK 0.1233 CHF 1.5376000000000001 █ KRW 0.001027 █ SGD 1.0036000000000000 CNY 0.1867 █ MXN 0.0811100000000000 █ TRY 0.0513 EUR 1.4695 █ NOK 0.1273 █ TWD 0.04276 GBP 1.7133000000000000 █ NZD 0.8044 █ USD 1.3606 HKD 0.1735 █ PEN 0.3684 █ ZAR 0.0730200000000000 # typical example of a mid-complexity ad-hoc query, using live web data jf -a ' latest = in.observations.last; rates = {k-`FX`-`CAD`: +v.v: latest.drop(`d`)}; { date: latest.d, rates.sort(k)@nice4@green... }' \ https://www.bankofcanada.ca/valet/observations/group/FX_RATES_DAILY/json?start_date=`date +%Y`-01-01 | sbs 3 date 2023-08-25 █ IDR 0.0001 █ RUB 0.0143 AUD 0.8725 █ INR 0.0165 █ SAR 0.3627 BRL 0.2791 █ JPY 0.0093 █ SEK 0.1233 CHF 1.5376 █ KRW 0.0010 █ SGD 1.0036 CNY 0.1867 █ MXN 0.0811 █ TRY 0.0513 EUR 1.4695 █ NOK 0.1273 █ TWD 0.0428 GBP 1.7133 █ NZD 0.8044 █ USD 1.3606 HKD 0.1735 █ PEN 0.3684 █ ZAR 0.0730 ###################################################################### # at some point I wanted to check some assumptions about plurals by # looking at examples of words ending with any vowel followed by `y` jf -a 'in.lower.lines.filter(v ~ `[aeiou]y$`)' words.txt.gz | head 1,533 items abacay abay abbey abey abray absey accloy accoy ackey ###################################################################### # get the playtime for all playable media files in the jf-demo folder jf -from=b -a '{k: try(v.duration, skip): in}.sort(-v)' *.* 3x3.mp4 1.802 beats.wav 1.5 2048hz Clicks.m4a 1.022 # get more info about all files in the jf-demo folder jf -from=b -a '{k: v.mediainfo: in}.denil(`text/plain`).sort(-v.size)' *.* | head -n 20 movies.json mime application/json size 3,386,802 duration NaN width NaN height NaN depth NaN thumbnail text/plain words.txt.gz mime application/gzip size 1,086,426 duration NaN width NaN height NaN depth NaN thumbnail text/plain e-digits.txt mime text/plain size 1,000,002 duration NaN ###################################################################### # wondering how long float64 mantissas will work as unix-style timestamps... # are those in millionths or billionths of a second? jf -q '2**{52,53,64}/{1e6,1e9}/day/365.25+1970' 52 1000000 2,112.710460471345 1000000000 1,970.142710460471 53 1000000 2,255.420920942689 1000000000 1,970.2854209209427 64 1000000 586,512.0460906264 1000000000 2,554.5420460906266 # you say about 1500 each day, what range is that a year? jf -q 1500.fuzz*[365,366].kv 1450 365 529,250 366 530,700 1500 365 547,500 366 549,000 1550 365 565,750 366 567,300 # now you tell me about 1400-1500 a day, so between 1400 and 1500 a day... jf -q [1400,1500].kv*[365,366].kv 1400 365 511,000 366 512,400 1500 365 547,500 366 549,000 # partial ASCII table jf -q '{v: v.ord: space+visascii}' | sbs 32 █ + 43 █ 6 54 █ A 65 █ L 76 █ W 87 █ b 98 █ m 109 █ x 120 ! 33 █ , 44 █ 7 55 █ B 66 █ M 77 █ X 88 █ c 99 █ n 110 █ y 121 " 34 █ - 45 █ 8 56 █ C 67 █ N 78 █ Y 89 █ d 100 █ o 111 █ z 122 # 35 █ . 46 █ 9 57 █ D 68 █ O 79 █ Z 90 █ e 101 █ p 112 █ { 123 $ 36 █ / 47 █ : 58 █ E 69 █ P 80 █ [ 91 █ f 102 █ q 113 █ | 124 % 37 █ 0 48 █ ; 59 █ F 70 █ Q 81 █ \ 92 █ g 103 █ r 114 █ } 125 & 38 █ 1 49 █ < 60 █ G 71 █ R 82 █ ] 93 █ h 104 █ s 115 █ ~ 126 ' 39 █ 2 50 █ = 61 █ H 72 █ S 83 █ ^ 94 █ i 105 █ t 116 █ ( 40 █ 3 51 █ > 62 █ I 73 █ T 84 █ _ 95 █ j 106 █ u 117 █ ) 41 █ 4 52 █ ? 63 █ J 74 █ U 85 █ ` 96 █ k 107 █ v 118 █ * 42 █ 5 53 █ @ 64 █ K 75 █ V 86 █ a 97 █ l 108 █ w 119 █ # partial ASCII table; worse version, but shows pipes and func `map` jf -q 'space.ord..126 ; _.map(v.chr, v)' | sbs 32 █ + 43 █ 6 54 █ A 65 █ L 76 █ W 87 █ b 98 █ m 109 █ x 120 ! 33 █ , 44 █ 7 55 █ B 66 █ M 77 █ X 88 █ c 99 █ n 110 █ y 121 " 34 █ - 45 █ 8 56 █ C 67 █ N 78 █ Y 89 █ d 100 █ o 111 █ z 122 # 35 █ . 46 █ 9 57 █ D 68 █ O 79 █ Z 90 █ e 101 █ p 112 █ { 123 $ 36 █ / 47 █ : 58 █ E 69 █ P 80 █ [ 91 █ f 102 █ q 113 █ | 124 % 37 █ 0 48 █ ; 59 █ F 70 █ Q 81 █ \ 92 █ g 103 █ r 114 █ } 125 & 38 █ 1 49 █ < 60 █ G 71 █ R 82 █ ] 93 █ h 104 █ s 115 █ ~ 126 ' 39 █ 2 50 █ = 61 █ H 72 █ S 83 █ ^ 94 █ i 105 █ t 116 █ ( 40 █ 3 51 █ > 62 █ I 73 █ T 84 █ _ 95 █ j 106 █ u 117 █ ) 41 █ 4 52 █ ? 63 █ J 74 █ U 85 █ ` 96 █ k 107 █ v 118 █ * 42 █ 5 53 █ @ 64 █ K 75 █ V 86 █ a 97 █ l 108 █ w 119 █ # on the way to PCM/wav-related calculation below... jf -n '{44_100,48_000}' { "44100": 44100, "48000": 48000 } # getting there... jf -n '{44_100,48_000}*{mono:1,stereo:2}*2' { "44100": { "mono": 88200, "stereo": 176400 }, "48000": { "mono": 96000, "stereo": 192000 } } # calculate PCM time-durations of 4GB, the max size for .wav files jf -n '{44_100,48_000}*{mono:1,stereo:2}*2 ; 4*gb/_ ; _@s2hms' { "44100": { "mono": "13:31:35.77", "stereo": "06:45:47.89" }, "48000": { "mono": "12:25:39.24", "stereo": "06:12:49.62" } } # KBs per minute for common MP3/AAC CBR settings jf -q '{`${64*v}k`: 8*v: 2..4} * {v.fix1: v: .5*20.iota} * 60' | sbs 3 128k █ 192k █ 256k 0.5 480 █ 0.5 720 █ 0.5 960 1.0 960 █ 1.0 1,440 █ 1.0 1,920 1.5 1,440 █ 1.5 2,160 █ 1.5 2,880 2.0 1,920 █ 2.0 2,880 █ 2.0 3,840 2.5 2,400 █ 2.5 3,600 █ 2.5 4,800 3.0 2,880 █ 3.0 4,320 █ 3.0 5,760 3.5 3,360 █ 3.5 5,040 █ 3.5 6,720 4.0 3,840 █ 4.0 5,760 █ 4.0 7,680 4.5 4,320 █ 4.5 6,480 █ 4.5 8,640 5.0 4,800 █ 5.0 7,200 █ 5.0 9,600 5.5 5,280 █ 5.5 7,920 █ 5.5 10,560 6.0 5,760 █ 6.0 8,640 █ 6.0 11,520 6.5 6,240 █ 6.5 9,360 █ 6.5 12,480 7.0 6,720 █ 7.0 10,080 █ 7.0 13,440 7.5 7,200 █ 7.5 10,800 █ 7.5 14,400 8.0 7,680 █ 8.0 11,520 █ 8.0 15,360 8.5 8,160 █ 8.5 12,240 █ 8.5 16,320 9.0 8,640 █ 9.0 12,960 █ 9.0 17,280 9.5 9,120 █ 9.5 13,680 █ 9.5 18,240 10.0 9,600 █ 10.0 14,400 █ 10.0 19,200 ###################################################################### # fs is one of the few funcs which spontaneously looks at your files jf -q 'dot.fs.sort(-v)' movies.json 3,386,802 words.txt.gz 1,086,426 e-digits.txt 1,000,002 pi-digits.txt 1,000,002 top-100k-domains.csv.gz 913,806 data-uris.html 800,155 movies.json.gz 743,003 na-pop-density-map-2020-shrunk.png 330,005 cadex.json 284,933 timezones.jsonl 273,235 terminal-examples.html 174,922 beats.wav 144,046 examples.html 132,726 3x3.mp4 113,324 no-data.html 90,136 first-10000-primes.jsonl 58,982 google-com.json 51,165 cadex.html 34,052 terminal-examples.ansi 20,786 e-digits.html 19,325 cadex.json.gz 15,556 country-info.tsv 13,881 terminal-examples.sh 10,633 2048hz Clicks.m4a 9,928 tsconfig.json 6,792 demo-commands.txt 5,314 no-data-examples.jf 5,163 cadex-example.jf 3,113 e-digits-example.jf 1,898 e-digits.ansi 1,825 browser-popup-examples.sh 845 rebuild.sh 839 strcap.jf 408 podcast-feeds.txt 336 Cargo.toml 211 primes-up-to.sh 194 # group by common file extension, sorted for easier eye-scanning jf -q 'dot.fs.sort(-v).group(k.ext).sort(k)' .ansi terminal-examples.ansi 20,786 e-digits.ansi 1,825 .gz words.txt.gz 1,086,426 top-100k-domains.csv.gz 913,806 movies.json.gz 743,003 cadex.json.gz 15,556 .html data-uris.html 800,155 terminal-examples.html 174,922 examples.html 132,726 no-data.html 90,136 cadex.html 34,052 e-digits.html 19,325 .jf no-data-examples.jf 5,163 cadex-example.jf 3,113 e-digits-example.jf 1,898 strcap.jf 408 .json movies.json 3,386,802 cadex.json 284,933 google-com.json 51,165 tsconfig.json 6,792 .jsonl timezones.jsonl 273,235 first-10000-primes.jsonl 58,982 .m4a 2048hz Clicks.m4a 9,928 .mp4 3x3.mp4 113,324 .png na-pop-density-map-2020-shrunk.png 330,005 .sh terminal-examples.sh 10,633 browser-popup-examples.sh 845 rebuild.sh 839 primes-up-to.sh 194 .toml Cargo.toml 211 .tsv country-info.tsv 13,881 .txt e-digits.txt 1,000,002 pi-digits.txt 1,000,002 demo-commands.txt 5,314 podcast-feeds.txt 336 .wav beats.wav 144,046 # now reverse sort by total byte-weight for each such category jf -q 'dot.fs.sort(-v).group(k.ext).sort(-v.sum())' .json movies.json 3,386,802 cadex.json 284,933 google-com.json 51,165 tsconfig.json 6,792 .gz words.txt.gz 1,086,426 top-100k-domains.csv.gz 913,806 movies.json.gz 743,003 cadex.json.gz 15,556 .txt e-digits.txt 1,000,002 pi-digits.txt 1,000,002 demo-commands.txt 5,314 podcast-feeds.txt 336 .html data-uris.html 800,155 terminal-examples.html 174,922 examples.html 132,726 no-data.html 90,136 cadex.html 34,052 e-digits.html 19,325 .jsonl timezones.jsonl 273,235 first-10000-primes.jsonl 58,982 .png na-pop-density-map-2020-shrunk.png 330,005 .wav beats.wav 144,046 .mp4 3x3.mp4 113,324 .ansi terminal-examples.ansi 20,786 e-digits.ansi 1,825 .tsv country-info.tsv 13,881 .sh terminal-examples.sh 10,633 browser-popup-examples.sh 845 rebuild.sh 839 primes-up-to.sh 194 .jf no-data-examples.jf 5,163 cadex-example.jf 3,113 e-digits-example.jf 1,898 strcap.jf 408 .m4a 2048hz Clicks.m4a 9,928 .toml Cargo.toml 211 # building out a pipeline starting from jeff jf -n -to=lines '[`${v.nice0.rpad(12)}${k}`: dot.fs.sort(-v)]' 3,386,802 movies.json 1,086,426 words.txt.gz 1,000,002 e-digits.txt 1,000,002 pi-digits.txt 913,806 top-100k-domains.csv.gz 800,155 data-uris.html 743,003 movies.json.gz 330,005 na-pop-density-map-2020-shrunk.png 284,933 cadex.json 273,235 timezones.jsonl 174,922 terminal-examples.html 144,046 beats.wav 132,726 examples.html 113,324 3x3.mp4 90,136 no-data.html 58,982 first-10000-primes.jsonl 51,165 google-com.json 34,052 cadex.html 20,786 terminal-examples.ansi 19,325 e-digits.html 15,556 cadex.json.gz 13,881 country-info.tsv 10,633 terminal-examples.sh 9,928 2048hz Clicks.m4a 6,792 tsconfig.json 5,314 demo-commands.txt 5,163 no-data-examples.jf 3,113 cadex-example.jf 1,898 e-digits-example.jf 1,825 e-digits.ansi 845 browser-popup-examples.sh 839 rebuild.sh 408 strcap.jf 336 podcast-feeds.txt 211 Cargo.toml 194 primes-up-to.sh # ecoli -ext colors lines by unique file extension; sbs means `side-by-side` jf -n -to=lines '[`${v.nice0.rpad9} ${k}`: dot.fs.sort(-v)]' | \ ecoli -ext | sbs 2 3,386,802 movies.json █ 20,786 terminal-examples.ansi 1,086,426 words.txt.gz █ 19,325 e-digits.html 1,000,002 e-digits.txt █ 15,556 cadex.json.gz 1,000,002 pi-digits.txt █ 13,881 country-info.tsv 913,806 top-100k-domains.csv.gz █ 10,633 terminal-examples.sh 800,155 data-uris.html █ 9,928 2048hz Clicks.m4a 743,003 movies.json.gz █ 6,792 tsconfig.json 330,005 na-pop-density-map-2020-shrunk.png █ 5,314 demo-commands.txt 284,933 cadex.json █ 5,163 no-data-examples.jf 273,235 timezones.jsonl █ 3,113 cadex-example.jf 174,922 terminal-examples.html █ 1,898 e-digits-example.jf 144,046 beats.wav █ 1,825 e-digits.ansi 132,726 examples.html █ 845 browser-popup-examples.sh 113,324 3x3.mp4 █ 839 rebuild.sh 90,136 no-data.html █ 408 strcap.jf 58,982 first-10000-primes.jsonl █ 336 podcast-feeds.txt 51,165 google-com.json █ 211 Cargo.toml 34,052 cadex.html █ 194 primes-up-to.sh ###################################################################### # calculate the first 100 fibonacci numbers: using bigint values allows using # different limits without worries, since float64 starts giving wrong results # at around 80 items; if float64s were used instead, this algorithm would be # constant-space and linear-time echo 100 | jf -to=a 'a = 1n; b = 0n; in.map(v.nth, t = b; b = a+b; a = t; b)' 1st 1n 2nd 1n 3rd 2n 4th 3n 5th 5n 6th 8n 7th 13n 8th 21n 9th 34n 10th 55n 11th 89n 12th 144n 13th 233n 14th 377n 15th 610n 16th 987n 17th 1,597n 18th 2,584n 19th 4,181n 20th 6,765n 21st 10,946n 22nd 17,711n 23rd 28,657n 24th 46,368n 25th 75,025n 26th 121,393n 27th 196,418n 28th 317,811n 29th 514,229n 30th 832,040n 31st 1,346,269n 32nd 2,178,309n 33rd 3,524,578n 34th 5,702,887n 35th 9,227,465n 36th 14,930,352n 37th 24,157,817n 38th 39,088,169n 39th 63,245,986n 40th 102,334,155n 41st 165,580,141n 42nd 267,914,296n 43rd 433,494,437n 44th 701,408,733n 45th 1,134,903,170n 46th 1,836,311,903n 47th 2,971,215,073n 48th 4,807,526,976n 49th 7,778,742,049n 50th 12,586,269,025n 51st 20,365,011,074n 52nd 32,951,280,099n 53rd 53,316,291,173n 54th 86,267,571,272n 55th 139,583,862,445n 56th 225,851,433,717n 57th 365,435,296,162n 58th 591,286,729,879n 59th 956,722,026,041n 60th 1,548,008,755,920n 61st 2,504,730,781,961n 62nd 4,052,739,537,881n 63rd 6,557,470,319,842n 64th 10,610,209,857,723n 65th 17,167,680,177,565n 66th 27,777,890,035,288n 67th 44,945,570,212,853n 68th 72,723,460,248,141n 69th 117,669,030,460,994n 70th 190,392,490,709,135n 71st 308,061,521,170,129n 72nd 498,454,011,879,264n 73rd 806,515,533,049,393n 74th 1,304,969,544,928,657n 75th 2,111,485,077,978,050n 76th 3,416,454,622,906,707n 77th 5,527,939,700,884,757n 78th 8,944,394,323,791,464n 79th 14,472,334,024,676,221n 80th 23,416,728,348,467,685n 81st 37,889,062,373,143,906n 82nd 61,305,790,721,611,591n 83rd 99,194,853,094,755,497n 84th 160,500,643,816,367,088n 85th 259,695,496,911,122,585n 86th 420,196,140,727,489,673n 87th 679,891,637,638,612,258n 88th 1,100,087,778,366,101,931n 89th 1,779,979,416,004,714,189n 90th 2,880,067,194,370,816,120n 91st 4,660,046,610,375,530,309n 92nd 7,540,113,804,746,346,429n 93rd 12,200,160,415,121,876,738n 94th 19,740,274,219,868,223,167n 95th 31,940,434,634,990,099,905n 96th 51,680,708,854,858,323,072n 97th 83,621,143,489,848,422,977n 98th 135,301,852,344,706,746,049n 99th 218,922,995,834,555,169,026n 100th 354,224,848,179,261,915,075n # calculate prime numbers using the algorithm with O(n**1.5) time-complexity echo 100 | jf -to=a 'in .filter(n => n != 1 && n.sqrt.all(div => div == 1 || n % div != 0)) .map((k+1).nth, v)' 1st 2 2nd 3 3rd 5 4th 7 5th 11 6th 13 7th 17 8th 19 9th 23 10th 29 11th 31 12th 37 13th 41 14th 43 15th 47 16th 53 17th 59 18th 61 19th 67 20th 71 21st 73 22nd 79 23rd 83 24th 89 25th 97 # calculate prime numbers in streaming mode seq 100 | jf -from=ev ' (in != 1 && in.sqrt.all(div => div == 1 || in % div != 0)) ? in : skip' | nl 1 2 2 3 3 5 4 7 5 11 6 13 7 17 8 19 9 23 10 29 11 31 12 37 13 41 14 43 15 47 16 53 17 59 18 61 19 67 20 71 21 73 22 79 23 83 24 89 25 97 ###################################################################### # JS-like array/string join order jf -q [dash,tile,fullblock]^space – ■ █ # python-like string/array join order jf -q space^[dash,tile,fullblock] – ■ █ # operator ^ is exactly like function `join` jf -q '[dash, tile, fullblock].join(space)' – ■ █ # old-fashioned way of calling `join` jf -q 'join([dash, tile, fullblock], space)' – ■ █ # joining 2 arrays makes a dict, but that's a digression... jf -q [upper[:3],dot,-3,slash]^[3,2,5.25,nil] ABC 3 . 2 -3 5.25 / null # subtraction to remove all substring occurrences jf -q [hex,digits,2*hex,2*hex-digits] 4 items 0123456789abcdefABCDEF 0123456789 0123456789abcdefABCDEF0123456789abcdefABCDEF abcdefABCDEFabcdefABCDEF # same thing, but easily guessable, if you don't know enough jeff jf -q '[hex, digits, 2*hex, replaceall(2*hex, digits, "")]' 4 items 0123456789abcdefABCDEF 0123456789 0123456789abcdefABCDEF0123456789abcdefABCDEF abcdefABCDEFabcdefABCDEF # break a string into pieces jf -q hex/3 3 items 01234567 89abcdef ABCDEF # multiplying/repeating a string the python way jf -to=l -n 80*dash –––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––– # everything is always just functions jf -to=l -n 'mul(80, dash)' –––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––– # again, 80 dashes jf -to=lines -n 80.dashes –––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––– # again, in the end everything is always just functions jf -to=lines -n 'dashes(80)' –––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––– # you can always call any func like a pretend-method jf -to=l -n '80.dashes()' –––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––– # talk about typing your thoughts out jf -to=l -n 2.slashes+space+77.dashes // ––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––– # if you're thinking in python, you might have come up with this instead jf -to=l -n 2*slash+space+77*dash // ––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––– # floating-point math jf -q [5.2,5.2**23,-75.abs/5,maxint] 4 items 5.2 29,381,698,884,548,508 15 9,007,199,254,740,992 # arbitrary-precision math jf -q [5.2i,5.2i**23i,-75i.abs/5i,maxint.bigint] 4 items 26 / 5 350,257,144,982,200,575,261,531,309,080,576 / 11,920,928,955,078,125 15n 9,007,199,254,740,992n # array conveniences (as a special case of automatic depth-first recursion) jf -q [3.iota...,3.iota.log10...] 6 items 1 2 3 0 0.3010299956639812 0.4771212547196624 ###################################################################### # function calls as you know them jf -q 'keys(styles)' 12 items reset normal invert inverted red green blue orange pink magenta gray black # you can always put the 1st arg before, method-style jf -q 'styles.keys()' 12 items reset normal invert inverted red green blue orange pink magenta gray black # dict `styles` has ANSI-codes as string values jf -q styles.red+tile+styles.reset ■ # object indexing with indices: remember that `red` was styles' 3rd key jf -q styles[2]+tile+styles.reset ■ # exclusive slicing, which mixes string-keys and indices: `magenta` is # styles' 8th key jf -q 'styles[`red`:7]@type' red string green string blue string # object slicing with string-keys, all-inclusive jf -q 'styles[`red`..`magenta`]@type' red string green string blue string orange string pink string magenta string # normally .. creates numeric arrays, but when used for # slicing containers it acts as an inclusive range jf -q 3.5..8 5 items 3.5 4.5 5.5 6.5 7.5 # normal .. works even backwards jf -q 5..3 3 items 5 4 3 jf -q 'styles[`red`..`magenta`] + tile + styles.reset' red ■ green ■ blue ■ orange ■ pink ■ magenta ■ # until `blue`, included jf -q 'styles[`red`..`blue`] + fullblock + styles.reset' red █ green █ blue █ # until right before `blue` jf -q 'styles[`red`:`blue`] + fullblock + styles.reset' red █ green █ ###################################################################### # number 1..20 in 5-item blocks seq 20 | awk 'NR%5 == 1 { print "" }; 1' 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 # jeff can read text `blocks` as arrays of strings/lines seq 20 | awk 'NR%5 == 1 { print "" }; 1' | jf -from=blocks [ [ "1", "2", "3", "4", "5" ], [ "6", "7", "8", "9", "10" ], [ "11", "12", "13", "14", "15" ], [ "16", "17", "18", "19", "20" ] ] # label each such array into a dict/object seq 20 | awk 'NR%5 == 1 { print "" }; 1' | \ jf -to=ansi -from=bl '[`one,two,three,four,five`/comma ^ v@n: in]' 4 items one 1 two 2 three 3 four 4 five 5 ········································ one 6 two 7 three 8 four 9 five 10 ········································ one 11 two 12 three 13 four 14 five 15 ········································ one 16 two 17 three 18 four 19 five 20 # let's use NaN instead of null as the missing-value marker seq 17 | awk 'NR%5 == 1 { print "" }; 1' | jf -from=bl -to=ansi ' // turn each string-array into an object [`one,two,three,four,five`/comma ^ v@n: in] // use nan as the default missing value, replacing null .revalue(v ?? nan)' 4 items one 1 two 2 three 3 four 4 five 5 ········································ one 6 two 7 three 8 four 9 five 10 ········································ one 11 two 12 three 13 four 14 five 15 ········································ one 16 two 17 three NaN four NaN five NaN ###################################################################### # memory stats cat /proc/meminfo MemTotal: 16734040 kB MemFree: 12913252 kB HighTotal: 0 kB HighFree: 0 kB LowTotal: 16734040 kB LowFree: 12913252 kB SwapTotal: 0 kB SwapFree: 11849323336 kB # read input as unix-conf: /proc/meminfo not a real file on windows, # so pipe it in using `cat`, which makes it work even on msys/windows cat /proc/meminfo | jf -from=uc -a MemTotal 16734040 kB MemFree 12913212 kB HighTotal 0 kB HighFree 0 kB LowTotal 16734040 kB LowFree 12913212 kB SwapTotal 0 kB SwapFree 11848123524 kB # all values are strings which could become numbers, if they weren't all # ending in ` kB`: get rid of it, then cat /proc/meminfo | jf -from=uc -a 'in - ` kB`' MemTotal 16734040 MemFree 12913212 HighTotal 0 HighFree 0 LowTotal 16734040 LowFree 12913212 SwapTotal 0 SwapFree 11845926868 # same as before, but also pipe result, bottom-call func `n` to turn all # strings into numbers, and finally reverse-sort by those same numbers cat /proc/meminfo | jf -from=uc -a 'in - ` kB` ; _@n.sort(-v)' SwapFree 11,843,682,616 MemTotal 16,734,040 LowTotal 16,734,040 MemFree 12,913,300 LowFree 12,913,300 HighTotal 0 HighFree 0 SwapTotal 0 # dividing 2 dictionaries cat /proc/meminfo | jf -from=uc -a 'in - ` kB` ; _@n.sort(-v) / {gb:gb,kb:kb}' SwapFree gb 11.028183881193399 kb 11,563,888.94140625 MemTotal gb 0.0155847892165184 kb 16,341.8359375 LowTotal gb 0.0155847892165184 kb 16,341.8359375 MemFree gb 0.0120264180004597 kb 12,610.61328125 LowFree gb 0.0120264180004597 kb 12,610.61328125 HighTotal gb 0 kb 0 HighFree gb 0 kb 0 SwapTotal gb 0 kb 0 # dividing 2 dictionaries, then transposing the result cat /proc/meminfo | \ jf -from=uc -a 'in - ` kB` ; _@n.sort(-v) / {gb:gb,kb:kb} ; _.tr()' gb SwapFree 11.026044465601444 MemTotal 0.0155847892165184 LowTotal 0.0155847892165184 MemFree 0.0120264291763306 LowFree 0.0120264291763306 HighTotal 0 HighFree 0 SwapTotal 0 kb SwapFree 11,561,645.6015625 MemTotal 16,341.8359375 LowTotal 16,341.8359375 MemFree 12,610.625 LowFree 12,610.625 HighTotal 0 HighFree 0 SwapTotal 0 # streaming-mode filter & calculator seq 20 | jf -from=el 'n = +in; (n % 2 == 0) ? skip : (n + tab + n**3.5)' 1 1 3 46.7653718043596882 5 279.5084971874737221 7 907.4926996951546698 9 2187.0000000000004547 11 4414.4275959630376747 13 7921.3961521943838306 15 13071.3187934500310803 17 20256.8179386595656979 19 29897.6878537454758771 # streaming-mode filter & calculator, with automatic JSON/number parsing seq 20 | jf -from=ev '(in % 2 == 0) ? skip : (in + tab + in**3.5)' 1 1 3 46.7653718043596882 5 279.5084971874737221 7 907.4926996951546698 9 2187.0000000000004547 11 4414.4275959630376747 13 7921.3961521943838306 15 13071.3187934500310803 17 20256.8179386595656979 19 29897.6878537454758771 ###################################################################### # input/output gzip (de)compression jf -n -to=json.gz lower | jf -from=j.gz -to=ansi abcdefghijklmnopqrstuvwxyz # input bzip decompression jf -n lower | bzip2 | jf -from=j.bz -to=ansi abcdefghijklmnopqrstuvwxyz # gzip decoding of generic bytes echo hello there | gzip | jf -from=b.gz -to=b hello there # bzip decoding of generic bytes echo hello there | bzip2 | jf -from=b.bz -to=b hello there # base64 encoding of generic bytes, limited to the first 50 output bytes fh bmp x*y | jf -from=b -to=l in.datauri[:50] data:image/x-bmp;base64,Qk02sHsBAAAAADYAAAAoAAAAAA # do the same thing, but with PNG data read as generic bytes fh 720p x*y | jf -from=b -to=l in.datauri[:50] data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABQAA # fh x*y | jf -from=b -to=text in.datauri | si