├── .gitignore ├── time ├── time.awk └── time_test.awk ├── math ├── abs.awk ├── pow.awk ├── is_num.awk ├── similarity.awk ├── dim.awk ├── expr.awk └── math_test.awk ├── strings ├── capitalize.awk ├── eval.awk ├── rindex.awk ├── prefix.awk ├── leven.awk └── strings_test.awk ├── .travis.yml ├── testing └── testing.awk ├── Makefile ├── sort ├── reverse.awk ├── insertion_sort.awk ├── heapsort.awk └── sort_test.awk ├── path ├── path_test.awk └── filepath.awk ├── log └── print.awk ├── array ├── array.awk └── array_test.awk ├── fmt └── print.awk └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | sample 2 | -------------------------------------------------------------------------------- /time/time.awk: -------------------------------------------------------------------------------- 1 | function time() { 2 | return strftime("%Y/%m/%d %H:%M:%S", systime()) 3 | } 4 | -------------------------------------------------------------------------------- /math/abs.awk: -------------------------------------------------------------------------------- 1 | # abs returns the absolute value of x 2 | function abs(x) { 3 | return (x < 0) ? -x : x 4 | } 5 | -------------------------------------------------------------------------------- /math/pow.awk: -------------------------------------------------------------------------------- 1 | # pow returns x**y, the base-x exponential of y 2 | function pow(x, y) { 3 | return x ^ y 4 | } 5 | -------------------------------------------------------------------------------- /math/is_num.awk: -------------------------------------------------------------------------------- 1 | # is_num returns 1 if an argument is a number 2 | function is_num(x) { 3 | return x == x + 0 4 | } 5 | -------------------------------------------------------------------------------- /strings/capitalize.awk: -------------------------------------------------------------------------------- 1 | # capitalize returns capitalized s 2 | function capitalize(s) { 3 | return toupper(substr(s, 1, 1)) substr(s, 2) 4 | } 5 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: objective-c 2 | 3 | install: 4 | - brew install gawk 5 | 6 | before_script: 7 | - gawk --version 8 | 9 | script: 10 | - make test 11 | -------------------------------------------------------------------------------- /strings/eval.awk: -------------------------------------------------------------------------------- 1 | # shellescape returns the string escaped so that it can be used in a shell command 2 | function shellescape(s) { 3 | gsub(/'/, "'\\''", s); 4 | 5 | return "'" s "'"; 6 | } 7 | -------------------------------------------------------------------------------- /math/similarity.awk: -------------------------------------------------------------------------------- 1 | @include "strings/leven.awk" 2 | 3 | # similarity returns degree of similarity between two arguments based on levenshtein distance 4 | function similarity(one, two) { 5 | return sprintf("%f", (1 - leven_dist(one, two) / (length(one) + length(two))) * 100) 6 | } 7 | -------------------------------------------------------------------------------- /testing/testing.awk: -------------------------------------------------------------------------------- 1 | @include "fmt/print.awk" 2 | @include "log/print.awk" 3 | 4 | function assert(test, msg) { 5 | if (test) { 6 | logger("SUCCESS", msg ? msg : "test") 7 | return 0 8 | } else { 9 | logger("ERROR", msg ? msg : "test") 10 | return 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | run: 2 | @AWKPATH=. sample.awk 3 | 4 | test: 5 | @AWKPATH=. awk -f array/array_test.awk 6 | @AWKPATH=. awk -f math/math_test.awk 7 | @AWKPATH=. awk -f path/path_test.awk 8 | @AWKPATH=. awk -f strings/strings_test.awk 9 | @AWKPATH=. awk -f sort/sort_test.awk 10 | @AWKPATH=. awk -f time/time_test.awk 11 | -------------------------------------------------------------------------------- /sort/reverse.awk: -------------------------------------------------------------------------------- 1 | @include "array/array.awk" 2 | 3 | function reverse(arr, i, t) { 4 | # count arr length 5 | c = sizeof(arr) 6 | 7 | # swap 8 | for (i in arr) { 9 | t[i] = arr[c--] 10 | } 11 | 12 | # redeclare 13 | for (i in arr) { 14 | arr[i] = t[i] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /time/time_test.awk: -------------------------------------------------------------------------------- 1 | @include "testing/testing.awk" 2 | @include "time/time.awk" 3 | 4 | BEGIN { 5 | fail += assert(match(time(),/[0-9]+\/[01][0-9]\/[0-3][0-9] [0-9]+:[0-9]+:[0-9]+/), "time() returns current time.") 6 | } 7 | 8 | @include "fmt/print.awk" 9 | BEGIN { 10 | if (fail > 0) { 11 | die("Error") 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /strings/rindex.awk: -------------------------------------------------------------------------------- 1 | # last_index returns the index of the last instance of find in s, 2 | # or 0 if find is not present 3 | function last_index(s, find, k, ns, nf) { 4 | ns = length(s) 5 | nf = length(find) 6 | for (k = ns+1-nf; k >= 1; k--) { 7 | if (substr(s, k, nf) == find) { 8 | return k 9 | } 10 | } 11 | return 0 12 | } 13 | -------------------------------------------------------------------------------- /sort/insertion_sort.awk: -------------------------------------------------------------------------------- 1 | # insertion sort arr[1..n] 2 | # stable, O(n^2) but fast for small arrays 3 | function sort(arr, n, i, j, t) { 4 | if (!n) { 5 | n = 1 6 | while (n in arr) { 7 | n++ 8 | } 9 | n-- 10 | } 11 | for (i = 2; i <= n; i++) { 12 | t = arr[i] 13 | for (j = i; j > 1 && arr[j-1] > t; j--) { 14 | arr[j] = arr[j-1] 15 | } 16 | arr[j] = t 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /math/dim.awk: -------------------------------------------------------------------------------- 1 | # max returns the larger of x or y 2 | function max(x, y) { 3 | return (x > y ? x : y) 4 | } 5 | 6 | # min returns the smaller of x or y 7 | function min(x, y) { 8 | return (x < y ? x : y) 9 | } 10 | 11 | # min3 returns the smaller of x, y or z 12 | function min3(x, y, z, result) { 13 | result = x 14 | 15 | if (y < result) { 16 | result = y 17 | } 18 | 19 | if (z < result) { 20 | result = z 21 | } 22 | 23 | return result 24 | } 25 | -------------------------------------------------------------------------------- /strings/prefix.awk: -------------------------------------------------------------------------------- 1 | # has_prefix tests whether the string s begins with pre. 2 | function has_prefix(s, pre, pre_len, s_len) { 3 | pre_len = length(pre) 4 | s_len = length(s) 5 | 6 | return pre_len <= s_len && substr(s, 1, pre_len) == pre 7 | } 8 | 9 | # has_suffix tests whether the string s ends with suf. 10 | function has_suffix(s, suf, suf_len, s_len) { 11 | suf_len = length(suf) 12 | s_len = length(s) 13 | 14 | return suf_len <= s_len && substr(s, s_len - suf_len + 1) == suf 15 | } 16 | -------------------------------------------------------------------------------- /path/path_test.awk: -------------------------------------------------------------------------------- 1 | @include "testing/testing.awk" 2 | @include "path/filepath.awk" 3 | 4 | BEGIN { 5 | fail += assert(dirname("/path/to/dir") == "/path/to", "dirname(/path/to/dir) equals to /path/to.") 6 | } 7 | 8 | BEGIN { 9 | fail += assert(basename("/path/to/dir") == "dir", "basename(/path/to/dir) equals to dir.") 10 | } 11 | 12 | BEGIN { 13 | fail += assert(is_abs("/path/to/dir"), "is_abs(/path/to/dir) returns true.") 14 | fail += assert(!is_abs("path/to/dir"), "is_abs(path/to/dir) returns false.") 15 | } 16 | 17 | @include "fmt/print.awk" 18 | BEGIN { 19 | if (fail > 0) { 20 | die("Error") 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /math/expr.awk: -------------------------------------------------------------------------------- 1 | # floo returns the greatest integer value less than or equal to x. 2 | function floor(x) { 3 | if (int(x) == x) { 4 | return x; 5 | } else if (x > 0){ 6 | return int(x); 7 | } else { 8 | return int(x) - 1; 9 | } 10 | } 11 | 12 | # ceil returns the least integer value greater than or equal to x. 13 | function ceil(x) { 14 | if (int(x) == x) { 15 | return x; 16 | } else if (x > 0) { 17 | return int(x) + 1; 18 | } else { 19 | return x; 20 | } 21 | } 22 | 23 | # round returns the rounded value to x 24 | function round(x) { 25 | if (x > 0) { 26 | return int(x + 0.5); 27 | } else { 28 | return int(x - 0.5); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /log/print.awk: -------------------------------------------------------------------------------- 1 | @include "fmt/print.awk" 2 | @include "time/time.awk" 3 | 4 | function logger(method, msg, color) { 5 | switch (method) { 6 | case "TITLE": 7 | color = "Yellow" 8 | break 9 | case "ERROR": 10 | color = "Red" 11 | break 12 | case "WARN": 13 | color = "Red" 14 | break 15 | case "INFO": 16 | color = "Green" 17 | break 18 | case "SUCCESS": 19 | color = "Green" 20 | break 21 | default: 22 | color = "None" 23 | break 24 | } 25 | print "[" colour("Magenta") time() colour("None") "]" colour(color) " " msg colour("None") 26 | } 27 | -------------------------------------------------------------------------------- /strings/leven.awk: -------------------------------------------------------------------------------- 1 | @include "math/dim.awk" 2 | 3 | # leven_dist returns the Levenshtein distance two text string 4 | function leven_dist(a, b) { 5 | lena = length(a); 6 | lenb = length(b); 7 | 8 | if (lena == 0) { 9 | return lenb; 10 | } 11 | if (lenb == 0) { 12 | return lena; 13 | } 14 | 15 | for (row = 1; row <= lena; row++) { 16 | m[row,0] = row 17 | } 18 | for (col = 1; col <= lenb; col++) { 19 | m[0,col] = col 20 | } 21 | 22 | for (row = 1; row <= lena; row++) { 23 | ai = substr(a, row, 1) 24 | for (col = 1; col <= lenb; col++) { 25 | bi = substr(b, col, 1) 26 | if (ai == bi) { 27 | cost = 0 28 | } else { 29 | cost = 1 30 | } 31 | m[row,col] = min3(m[row-1,col]+1, m[row,col-1]+1, m[row-1,col-1]+cost) 32 | } 33 | } 34 | 35 | return m[lena,lenb] 36 | } 37 | -------------------------------------------------------------------------------- /path/filepath.awk: -------------------------------------------------------------------------------- 1 | @include "strings/prefix.awk" 2 | 3 | # dirname returns all but the last element of pathname, typically the pathname's directory. 4 | function dirname(pathname) { 5 | if (!sub(/\/[^\/]*\/?$/, "", pathname)) { 6 | return "." 7 | } else if (pathname != "") { 8 | return pathname 9 | } else { 10 | return "/" 11 | } 12 | } 13 | 14 | # basename returns the last element of pathname. 15 | function basename(pathname, suffix) { 16 | sub(/\/$/, "", pathname) 17 | if (pathname == "") { 18 | return "/" 19 | } 20 | 21 | sub(/^.*\//, "", pathname) 22 | 23 | if (suffix != "" && has_suffix(pathname, suffix)) { 24 | pathname = substr(pathname, 1, length(pathname) - length(suffix)) 25 | } 26 | 27 | return pathname 28 | } 29 | 30 | # is_abs returns true if the path is absolute. 31 | function is_abs(pathname) { 32 | return length(pathname) > 0 && has_prefix(pathname, "/") 33 | } 34 | -------------------------------------------------------------------------------- /math/math_test.awk: -------------------------------------------------------------------------------- 1 | @include "testing/testing.awk" 2 | @include "math/abs.awk" 3 | @include "math/dim.awk" 4 | @include "math/expr.awk" 5 | @include "math/is_num.awk" 6 | @include "math/pow.awk" 7 | 8 | # abs 9 | BEGIN { 10 | fail += assert(abs(2) == 2, "abs(2) is 2.") 11 | fail += assert(abs(-3) == 3, "abs(-3) is 3.") 12 | } 13 | 14 | BEGIN { 15 | fail += assert(max(2, 3) == 3, "3 is greater than 2.") 16 | fail += assert(min(2, 3) == 2, "2 is less than 3.") 17 | } 18 | 19 | BEGIN { 20 | fail += assert(floor(2.3) == 2, "floor(2.3) equals to 2.") 21 | fail += assert(ceil(2.3) == 3, "ceil(2.3) equals to 3.") 22 | fail += assert(round(2.3) == 2, "round(2) equals to 2.") 23 | } 24 | 25 | BEGIN { 26 | fail += assert(is_num(2), "is_num(2) returns true.") 27 | fail += assert(is_num("2"), "is_num(\"2\") returns true.") 28 | fail += assert(!is_num("a"), "is_num(\"a\") returns false.") 29 | } 30 | 31 | BEGIN { 32 | fail += assert(pow(2, 3) == 8, "2**3 equals to 8.") 33 | } 34 | 35 | BEGIN { 36 | if (fail > 0) { 37 | die("Error") 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /strings/strings_test.awk: -------------------------------------------------------------------------------- 1 | @include "testing/testing.awk" 2 | @include "strings/capitalize.awk" 3 | @include "strings/prefix.awk" 4 | @include "strings/leven.awk" 5 | @include "strings/rindex.awk" 6 | 7 | BEGIN { 8 | fail += assert(capitalize("abc") == "Abc", "capitalize(\"abc\") equals to \"Abc\".") 9 | } 10 | 11 | BEGIN { 12 | fail += assert(has_prefix("abc", "a"), "has_prefix(\"abc\", \"a\") returns true.") 13 | } 14 | 15 | BEGIN { 16 | fail += assert(has_suffix("abc", "c"), "has_suffix(\"abc\", \"c\") returns true.") 17 | } 18 | 19 | BEGIN { 20 | fail += assert(leven_dist("abc", "aba") == 1, "leven_dist(\"abc\", \"aba\") equals to 1.") 21 | fail += assert(leven_dist("abc", "ab") == 1, "leven_dist(\"abc\", \"ab\") equals to 1.") 22 | fail += assert(leven_dist("abc", "abc") == 0, "leven_dist(\"abc\", \"abc\") equals to 0.") 23 | } 24 | 25 | BEGIN { 26 | fail += assert(last_index("abcabc", "ab") == 4, "last_index(\"abcabc\", \"ab\") equals to 4.") 27 | } 28 | 29 | @include "fmt/print.awk" 30 | BEGIN { 31 | if (fail > 0) { 32 | die("Error") 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /sort/heapsort.awk: -------------------------------------------------------------------------------- 1 | # heapsort 2 | # also unstable, and unlike merge and quicksort it relies on random-access so has poorer cache performance 3 | # advantage over quicksort is that its worst-case same as avg: O(n log n) 4 | # this presentation based on http://dada.perl.it/shootout/heapsort.lua5.html 5 | function heapsort(arr, n, c, p, t, i) { 6 | if (!n) { 7 | n = 1 8 | while (n in arr) { 9 | n++ 10 | } 11 | n-- 12 | } 13 | 14 | # Build heap with greatest element at top 15 | i = int(n/2) + 1 16 | while (1) { 17 | if (i > 1) { 18 | i-- 19 | t = arr[i] 20 | } else { 21 | t = arr[n] 22 | arr[n] = arr[1] 23 | n-- 24 | if (n == 1) { 25 | arr[1] = t 26 | return 27 | } 28 | } 29 | for (p = i; (c = 2*p) <= n; p = c) { 30 | if ((c < n) && (arr[c] < arr[c+1])) { 31 | c++ 32 | } 33 | if (t < arr[c]) { 34 | arr[p] = arr[c] 35 | } else { 36 | break 37 | } 38 | } 39 | arr[p] = t 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /sort/sort_test.awk: -------------------------------------------------------------------------------- 1 | @include "testing/testing.awk" 2 | @include "sort/insertion_sort.awk" 3 | @include "sort/heapsort.awk" 4 | @include "sort/reverse.awk" 5 | 6 | @include "array/array.awk" 7 | 8 | BEGIN { 9 | arr1[1] = "5" 10 | arr1[2] = "a" 11 | arr1[3] = "3" 12 | arr1[4] = "0" 13 | arr2[1] = "0" 14 | arr2[2] = "3" 15 | arr2[3] = "5" 16 | arr2[4] = "a" 17 | sort(arr1) 18 | fail += assert(equals(arr1, arr2), "sort(arr1) is ok.") 19 | clear(arr1) 20 | clear(arr2) 21 | } 22 | 23 | BEGIN { 24 | arr1[1] = "5" 25 | arr1[2] = "a" 26 | arr1[3] = "3" 27 | arr1[4] = "0" 28 | arr2[1] = "0" 29 | arr2[2] = "3" 30 | arr2[3] = "5" 31 | arr2[4] = "a" 32 | heapsort(arr1) 33 | fail += assert(equals(arr1, arr2), "heapsort(arr1) is ok.") 34 | clear(arr1) 35 | clear(arr2) 36 | } 37 | 38 | BEGIN { 39 | arr1[1] = "5" 40 | arr1[2] = "a" 41 | arr1[3] = "3" 42 | arr1[4] = "0" 43 | arr2[1] = "0" 44 | arr2[2] = "3" 45 | arr2[3] = "a" 46 | arr2[4] = "5" 47 | reverse(arr1) 48 | fail += assert(equals(arr1, arr2), "reverse(arr1) is ok.") 49 | clear(arr1) 50 | clear(arr2) 51 | } 52 | 53 | @include "fmt/print.awk" 54 | BEGIN { 55 | if (fail > 0) { 56 | die("Error") 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /array/array.awk: -------------------------------------------------------------------------------- 1 | # is_empty returns true if arr has one or more elements 2 | function is_empty(arr, i) { 3 | for (i in arr) { 4 | return 0 5 | } 6 | return 1 7 | } 8 | 9 | function acopy(arr1, arr2, i) { 10 | for (i in arr1) { 11 | arr2[i] = arr1[i]; 12 | } 13 | } 14 | 15 | function sizeof(arr, i, c) { 16 | for (i in arr) { 17 | c++ 18 | } 19 | 20 | return c 21 | } 22 | 23 | function has_value(arr, value, k) { 24 | for (k in arr) { 25 | if (arr[k] == value) { 26 | return 1 27 | } 28 | } 29 | 30 | return 0 31 | } 32 | 33 | function join(a, start, end, sep, result, i) { 34 | sep = sep ? start : " " 35 | start = start ? start : 1 36 | end = end ? end : sizeof(a) 37 | if (sep == SUBSEP) { 38 | sep = "" 39 | } 40 | result = a[start] 41 | for (i = start + 1; i <= end; i++) { 42 | result = result sep a[i] 43 | } 44 | return result 45 | } 46 | 47 | function equals(arr1, arr2) { 48 | if (sizeof(arr1) != sizeof(arr2)) { 49 | return 0 50 | } 51 | 52 | for (i in arr1) { 53 | if (arr1[i] != arr2[i]) { 54 | return 0 55 | } 56 | } 57 | 58 | return 1 59 | } 60 | 61 | function clear(arr) { 62 | for (i in arr) { 63 | delete arr[i] 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /array/array_test.awk: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env gawk -f 2 | 3 | @include "testing/testing.awk" 4 | @include "array/array.awk" 5 | 6 | # is_empty 7 | BEGIN { 8 | fail += assert(is_empty(arr), "is_empty returns true") 9 | arr[1] = "val" 10 | fail += assert(!is_empty(arr), "is_empty returns false") 11 | clear(arr) 12 | } 13 | 14 | # clear 15 | BEGIN { 16 | arr[1] = "val" 17 | fail += assert(!is_empty(arr), "arr exists") 18 | clear(arr) 19 | fail += assert(is_empty(arr), "arr does not exist") 20 | } 21 | 22 | # sizeof 23 | BEGIN { 24 | arr[1] = "one" 25 | arr[2] = "two" 26 | fail += assert(sizeof(arr) == 2, "arr has two elements") 27 | clear(arr) 28 | } 29 | 30 | # equals 31 | BEGIN { 32 | arr1[1] = "one" 33 | arr1[2] = "two" 34 | arr2[1] = "one" 35 | arr2[2] = "two" 36 | fail += assert(equals(arr1, arr2), "equals returns true") 37 | clear(arr1) 38 | clear(arr2) 39 | 40 | arr1[1] = "one" 41 | arr1[2] = "two" 42 | arr2[1] = "one" 43 | fail += assert(!equals(arr1, arr2), "equals returns false") 44 | clear(arr1) 45 | clear(arr2) 46 | } 47 | 48 | # acopy 49 | BEGIN { 50 | arr1[1] = "one" 51 | arr1[2] = "two" 52 | acopy(arr1, arr2) 53 | fail += assert(equals(arr1, arr2), "arr equals to arr2") 54 | clear(arr1) 55 | clear(arr2) 56 | } 57 | 58 | # join 59 | BEGIN { 60 | arr[1] = "one" 61 | arr[2] = "two" 62 | fail += assert(join(arr) == "one two", "arr 'one,two' turns into 'one two'") 63 | clear(arr) 64 | } 65 | 66 | # has_value 67 | BEGIN { 68 | arr["key"] = "val" 69 | fail += assert(has_value(arr, "val"), "arr has val value") 70 | } 71 | 72 | @include "fmt/print.awk" 73 | BEGIN { 74 | if (fail > 0) { 75 | die("Error") 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /fmt/print.awk: -------------------------------------------------------------------------------- 1 | @include "strings/capitalize.awk" 2 | @include "math/is_num.awk" 3 | 4 | # die puts msg to stderr 5 | function die(msg) { 6 | printf("%s%s: %s%s\n", colour("Red"), ARGV[0], msg, colour("None")) >"/dev/stderr" 7 | exit 1 8 | } 9 | 10 | function name_to_number(name, predefined) { 11 | if (is_num(name)) 12 | return name; 13 | 14 | if (name in predefined) 15 | return predefined[name]; 16 | 17 | return name; 18 | } 19 | 20 | function colour(v1, v2, v3) { 21 | v1 = capitalize(v1) 22 | v2 = capitalize(v2) 23 | v3 = capitalize(v3) 24 | 25 | fgcolours["None"] = 0; 26 | fgcolours["Black"] = 30; 27 | fgcolours["Red"] = 31; 28 | fgcolours["Green"] = 32; 29 | fgcolours["Yellow"] = 33; 30 | fgcolours["Blue"] = 34; 31 | fgcolours["Magenta"] = 35; 32 | fgcolours["Cyan"] = 36; 33 | fgcolours["White"] = 37; 34 | 35 | bgcolours["None"] = 0; 36 | bgcolours["Black"] = 40; 37 | bgcolours["Red"] = 41; 38 | bgcolours["Green"] = 42; 39 | bgcolours["Yellow"] = 43; 40 | bgcolours["Blue"] = 44; 41 | bgcolours["Magenta"] = 45; 42 | bgcolours["Cyan"] = 46; 43 | bgcolours["White"] = 47; 44 | 45 | attributes["None"] = 0; 46 | attributes["Bold"] = 1; 47 | attributes["Underscore"] = 4; 48 | attributes["Blink"] = 5; 49 | attributes["ReverseVideo"] = 7; 50 | attributes["Concealed"] = 8; 51 | 52 | if (v3 == "" && v2 == "" && v1 == "") { 53 | return 54 | } 55 | 56 | if (v3 == "" && v2 == "") 57 | return sprintf("%c[%dm", 27, name_to_number(v1, fgcolours)); 58 | else if (v3 == "") 59 | return sprintf("%c[%d;%dm", 27, name_to_number(v1, bgcolours), name_to_number(v2, fgcolours)); 60 | else 61 | return sprintf("%c[%d;%d;%dm", 27, name_to_number(v1, attributes), name_to_number(v2, bgcolours), name_to_number(v3, fgcolours)); 62 | } 63 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Many AWK 2 | 3 | [![](https://img.shields.io/travis/b4b4r07/manyawk.svg?style=flat-square)][travis] 4 | [![](http://img.shields.io/badge/license-MIT-blue.svg?style=flat-square)][license] 5 | ![](https://img.shields.io/badge/AWK-gawk-orange.svg?style=flat-square) 6 | 7 | [travis]: https://travis-ci.org/b4b4r07/manyawk 8 | [license]: http://b4b4r07.mit-license.org 9 | 10 | :monkey: manyawk is the AWK library that provides many comprehensive AWK utility functions. 11 | 12 | ## Description 13 | 14 | This manyawk library structure is inspired by [Golang packages](https://golang.org/pkg/) structure. 15 | 16 | - [array](https://github.com/b4b4r07/manyawk/tree/master/array) 17 | - [fmt](https://github.com/b4b4r07/manyawk/tree/master/fmt) 18 | - [log](https://github.com/b4b4r07/manyawk/tree/master/log) 19 | - [math](https://github.com/b4b4r07/manyawk/tree/master/math) 20 | - [path](https://github.com/b4b4r07/manyawk/tree/master/path) 21 | - [sort](https://github.com/b4b4r07/manyawk/tree/master/sort) 22 | - [strings](https://github.com/b4b4r07/manyawk/tree/master/strings) 23 | - [testing](https://github.com/b4b4r07/manyawk/tree/master/testing) 24 | - [time](https://github.com/b4b4r07/manyawk/tree/master/time) 25 | 26 | ## Installation 27 | 28 | To get manyawk: 29 | 30 | ```console 31 | $ git clone https://github.com/b4b4r07/manyawk 32 | ``` 33 | 34 | Then you'll need to set the [AWKPATH](https://www.gnu.org/software/gawk/manual/html_node/AWKPATH-Variable.html#AWKPATH-Variable) environment variable to this library directory root when using manyawk. 35 | 36 | ```console 37 | $ export AWKPATH=/path/to/manyawk # this library 38 | ``` 39 | 40 | ## Usage 41 | 42 | You must load modules from manyawk you want to use and add `@include "module/module.awk"` to your awk script. 43 | 44 | ```awk 45 | #!/usr/bin/env gawk -f 46 | 47 | @include "math/similarity.awk" 48 | 49 | BEGIN { 50 | printf("%f%\n", similarity(ARGV[1], ARGV[2])) 51 | } 52 | ``` 53 | 54 | To save the awk script above as `leven_dist.awk`, and to run: 55 | 56 | ```console 57 | $ AWKPATH=. awk -f leven_dist.awk "awk is fun" "gawk is fun" 58 | 95.238095% 59 | ``` 60 | 61 | ## VS. 62 | 63 | - [e36freak/awk-libs - GitHub](https://github.com/e36freak/awk-libs) 64 | - [dubiousjim/awkenough - GitHub](https://github.com/dubiousjim/awkenough) 65 | 66 | ## License 67 | 68 | [MIT](http://b4b4r07.mit-license.org) © BABAROT (a.k.a. b4b4r07) --------------------------------------------------------------------------------