From 2fb17f7402e993d2f61eddaadd5b9f782c4649a3 Mon Sep 17 00:00:00 2001 From: Jephte Clain Date: Sun, 2 Apr 2017 19:09:51 +0400 Subject: [PATCH] =?UTF-8?q?impl=C3=A9menter=20dumpcsv=20--awk-map?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/ulib/awk | 112 +++++++++++++++++++++++++++++++++++++++++++++----- lib/ulib/base | 6 +++ 2 files changed, 107 insertions(+), 11 deletions(-) diff --git a/lib/ulib/awk b/lib/ulib/awk index 5bbb596..c242e6b 100644 --- a/lib/ulib/awk +++ b/lib/ulib/awk @@ -1758,7 +1758,7 @@ function sortcsv() { LANG=C lsortcsv "$@"; } ################################################################################ __DUMPCSV_HELP="\ -Afficher les champs spécifiés pour traitement par le shell +Afficher les champs spécifiés pour traitement par le shell ou par awk -S, --skip-lines nblines Sauter nblines au début du flux @@ -1785,7 +1785,7 @@ Afficher les champs spécifiés pour traitement par le shell Spécifier le nom à utiliser pour afficher les en-têtes avec l'option -h -n, --name NAME - Spécifier le nom à utiliser pour les options -f, -a, -b + Spécifier le nom à utiliser pour les options -f, -a, -b, -w -f, --function Afficher les champs comme l'appel d'une fonction, e.g: dump value00 value01... @@ -1815,6 +1815,28 @@ Afficher les champs spécifiés pour traitement par le shell Le nom du tableau est fixé à 'values'. L'option -n permet de spécifier le nom de la fonction, qui vaut 'dump' par défaut. Avec -h le nom par défaut est 'dumph' +-w, --awk-map + Afficher les champs comme une fonction awk qui permet de rechercher une + valeur et d'afficher la valeur correspondante. L'option -n permet de + spécifier le nom de la fonction, qui vaut 'mapval' par défaut. +--wtype TYPE + Spécifier le type de fonction à générer avec l'option --awk-map. Le type par + défaut est 'value' + Avec le type 'value', la fonction générée est de la forme dump(inval). Cette + fonction prend en argument la valeur de la colonne spécifiée avec --wscol, + et si cette valeur est trouvée dans les données, retourner la valeur de la + colonne spécifiée avec --wrcol + Avec le type 'array', la fonction générée est de la forme dump(inval, outvs) + Cette fonction prend en argument la valeur de la colonne spécifiée avec + --wscol, et si cette valeur est trouvée dans les données, le tableau outvs + est rempli avec les donnée de la ligne correspondante. +--wscol SFIELD + Nom du champ qui est cherché par la fonction générée avec l'option --awk-map + La valeur par défaut est '1', c'est à dire le premier champ. +--wrcol RFIELD + Nom du champ dont la valeur est retournée par la fonction générée avec + l'option '--awk-map --wtype value' en cas de correspondance. + La valeur par défaut est '2', c'est à dire le deuxième champ. -v, --var Affiche les champ en initialisant des variables, e.g: names=(header0 header1) @@ -1838,6 +1860,7 @@ function ldumpcsv() { eval "$(utools_local)" local skip= parse_headers=1 keepf skipf show_headers local dump=function reset=1 name hname + local wtype wscol wrcol parse_opts "${PRETTYOPTS[@]}" \ -S:,--skip:,--skip-lines:,--skiplines: skip= \ -H,--parse-headers parse_headers=1 \ @@ -1852,6 +1875,10 @@ function ldumpcsv() { --reset reset=1 \ --no-reset reset= \ -b,--array-function dump=array-function \ + -w,--awk-map dump=awk-map \ + --wtype: wtype= \ + --wscol: wscol= \ + --wrcol: wrcol= \ -v,--var dump=var \ @ args -- "$@" && set -- "${args[@]}" || die "$args" @@ -1876,13 +1903,64 @@ function ldumpcsv() { case "$dump" in function|array-function) name=dump;; array) name=values;; + awk-map) name=mapval;; esac fi + case "${wtype:-value}" in + array|a) wtype=array;; + value|v) wtype=value;; + esac + [ -n "$wscol" ] || wscol=1 + [ -n "$wrcol" ] || wrcol=2 local -a fields fields=("$@") - awkcsv "${args[@]}" -v show_headers:int="$show_headers" -v hname="$hname" -v name="$name" -v dump="$dump" -v reset_values:int="$reset" -v fields[@] -e ' + awkcsv "${args[@]}" -v show_headers:int="$show_headers" \ + -v hname="$hname" -v name="$name" -v dump="$dump" \ + -v reset_values:int="$reset" -v fields[@] \ + -v wtype="$wtype" -v wscol="$wscol" -v wrcol="$wrcol" \ + -e ' +function init_fields() { + if (do_once("init_fields")) { + if (fields_count == 0) { + array_copy(fields, HEADERS) + fields_count = array_len(fields) + } + } +} +function before_awkmap(name, wtype) { + if (do_once("before_awkmap")) { + if (wtype == "value") { + print "function " name "(inval) {" + } else if (wtype == "array") { + print "function " name "(inval, outvs) {" + } + } +} +function awkmap(inval, outval, values, count, wtype, i) { + if (wtype == "value") { + print "if (inval == " qawk(inval) ") return " qawk(outval) + } else if (wtype == "array") { + print "if (inval == " qawk(inval) ") {" + print "delete outvs" + for (i = 1; i <= count; i++) { + print "outvs[" i "] = " qawk(values[i]) + } + print "return 1" + print "}" + } +} +function after_awkmap() { + if (do_once("after_awkmap")) { + if (wtype == "value") { + print "return \"\"" + } else if (wtype == "array") { + print "return 0" + } + print "}" + } +} function dump_values(name, values, dump) { if (dump == "function") { print qarr(values, name) @@ -1899,12 +1977,8 @@ function dump_values(name, values, dump) { } } } -function init_fields() { - if (do_once("init_fields")) { - if (fields_count == 0) { - array_copy(fields, HEADERS) - fields_count = array_len(fields) - } +function before_dump() { + if (do_once("before_dump")) { if (show_headers) { dump_values(hname, fields, dump == "var"? "array": dump) } @@ -1922,10 +1996,26 @@ function init_fields() { values[i] = get(fields[i]) i++ } - dump_values(name, values, dump) + + if (dump == "awk-map") { + before_awkmap(name, wtype) + if (wscol ~ /^[0-9]+$/) inval = geti(wscol) + else inval = get(wscol) + if (wrcol ~ /^[0-9]+$/) outval = geti(wrcol) + else outval = get(wrcol) + awkmap(inval, outval, values, fields_count, wtype) + } else { + before_dump() + dump_values(name, values, dump) + } } END { - init_fields() + if (dump == "awk-map") { + before_awkmap(name, wtype) + after_awkmap() + } else { + before_dump() + } }' -a '' } diff --git a/lib/ulib/base b/lib/ulib/base index 0c5c5c1..81b9878 100644 --- a/lib/ulib/base +++ b/lib/ulib/base @@ -1780,6 +1780,12 @@ function unquote_html(s) { gsub(/&/, "\\&", s) return s } +function qawk(s) { + gsub(/\\/, "\\\\", s) + gsub(/"/, "\\\"", s) + gsub(/\n/, "\\n", s) + return "\"" s "\"" +} function qval(s) {'" gsub(/'/, \"'\\\\''\", s) return \"'\" s \"'\"