From b2c9f81545c3224626d327819289f300d5e78e7b Mon Sep 17 00:00:00 2001 From: Jephte Clain Date: Tue, 19 May 2015 17:24:44 +0400 Subject: [PATCH 1/2] =?UTF-8?q?uawk=20requi=C3=A8re=20maintenant=20de=20sp?= =?UTF-8?q?=C3=A9cifier=20le=20nom=20de=20l'outil?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- uawk | 153 +++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 91 insertions(+), 62 deletions(-) diff --git a/uawk b/uawk index 9ddf93a..5ed1e50 100755 --- a/uawk +++ b/uawk @@ -1,13 +1,13 @@ #!/bin/bash # -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8 -ALIASES=(awkrun awkfsv2csv awkcsv grepcsv mergecsv sortcsv) +TOOLS=(awkrun awkcsv grepcsv awkfsv2csv mergecsv sortcsv) if [ "$#" -eq 1 -a "$1" == --nutools-makelinks ]; then # créer les liens scriptname="$(basename "$0")" - for alias in "${ALIASES[@]}"; do - ln -s "$scriptname" "$alias" - ln -s "$scriptname" "l$alias" + for tool in "${TOOLS[@]}"; do + ln -s "$scriptname" "$tool" + ln -s "$scriptname" "l$tool" done exit 0 fi @@ -15,77 +15,46 @@ fi source "$(dirname "$0")/lib/ulib/ulib" || exit 1 urequire DEFAULTS awk -# si on lance le script uawk, donner la possibilité de choisir l'outil -if [ "$scriptname" == uawk ] && array_contains ALIASES "${1#l}"; then +# si on lance le script avec le nom uawk, il faut spécifier l'outil à +# utiliser +if [ "$scriptname" == uawk ]; then + if [ $# -eq 1 -a "$1" == --help ]; then + exit_with uecho "$scriptname: wrapper pour des outils implémentés en awk + +USAGE + $scriptname TOOL args... + +Les noms d'outils valides sont: ${TOOLS[*]} +Utiliser l'option --help pour obtenir de l'aide sur chacun des outils" + fi scriptname="$1" shift fi # choix de la version des scripts: tient compte de la locale ou non -if [ "${scriptname#l}" != "$scriptname" ]; then +tool="${scriptname#l}" +if [ "$tool" != "$scriptname" ]; then + toolprefix=l prefix=l Clang= else + toolprefix= prefix=c Clang=1 fi -if [ "${scriptname#l}" == "awkcsv" ]; then - [ $# -eq 1 -a "$1" == --help ] && exit_with uecho "$scriptname: wrapper autour de awk pour traiter des fichier csv -${Clang:+note: ce script ne tient pas compte de la locale: il travaille avec LANG=C -} -USAGE - $scriptname [-b before] -e script [-a after] -- [headers...] [-- inputfiles...] +# Aliases pour les noms d'outils +case "$tool" in +run) tool=awkrun;; +csv) tool=awkcsv;; +grep) tool=grepcsv;; +fsv2csv|fsv) tool=awkfsv2csv;; +merge) tool=mergecsv;; +sort) tool=sortcsv;; +esac +scriptname="$toolprefix$tool" -$__AWKCSV_HELP" - - "${prefix}awkcsv" "$@" - -elif [ "${scriptname#l}" == "grepcsv" ]; then - [ $# -eq 1 -a "$1" == --help ] && exit_with uecho "$scriptname: wrapper autour de awk pour rechercher des lignes d'un fichier csv -${Clang:+note: ce script ne tient pas compte de la locale: il travaille avec LANG=C -} -USAGE - $scriptname EXPR [inputfiles...] [-- headers...] - -$__GREPCSV_HELP" - - "${prefix}grepcsv" "$@" - -elif [ "${scriptname#l}" == "awkfsv2csv" ]; then - [ $# -eq 1 -a "$1" == --help ] && exit_with uecho "$scriptname: wrapper autour de awk pour transformer un fichier à colonnes fixes en fichier csv -${Clang:+note: ce script ne tient pas compte de la locale: il travaille avec LANG=C -} -USAGE - $scriptname [options] -- [header:sizes...] [-- inputfiles...] - -$__AWKFSV2CSV_HELP" - - "${prefix}awkfsv2csv" "$@" - -elif [ "${scriptname#l}" == "mergecsv" ]; then - [ $# -eq 1 -a "$1" == --help ] && exit_with uecho "$scriptname: fusionner deux fichiers csv sur un champ commun -${Clang:+note: ce script ne tient pas compte de la locale: il travaille avec LANG=C -} -USAGE - $scriptname [options] left right -k field - -$__MERGECSV_HELP" - - "${prefix}mergecsv" "$@" - -elif [ "${scriptname#l}" == "sortcsv" ]; then - [ $# -eq 1 -a "$1" == --help ] && exit_with uecho "$scriptname: trier un fichier csv sur un champ -${Clang:+note: ce script ne tient pas compte de la locale: il travaille avec LANG=C -} -USAGE - $scriptname [options] input -k field - -$__SORTCSV_HELP" - - "${prefix}sortcsv" "$@" - -else +if [ "$tool" == "awkrun" ]; then [ $# -eq 1 -a "$1" == --help ] && exit_with uecho "$scriptname: wrapper autour de awk rajoutant des fonctions supplémentaires ${Clang:+note: ce script ne tient pas compte de la locale: il travaille avec LANG=C } @@ -97,4 +66,64 @@ Lancer awk avec un script préparé de la manière spécifiée ci dessous. $__AWKDEF_HELP" "${prefix}awkrun" -f "$@" + +elif [ "$tool" == "awkcsv" ]; then + [ $# -eq 1 -a "$1" == --help ] && exit_with uecho "$scriptname: wrapper autour de awk pour traiter des fichier csv +${Clang:+note: ce script ne tient pas compte de la locale: il travaille avec LANG=C +} +USAGE + $scriptname [-b before] -e script [-a after] -- [headers...] [-- inputfiles...] + +$__AWKCSV_HELP" + + "${prefix}awkcsv" "$@" + +elif [ "$tool" == "grepcsv" ]; then + [ $# -eq 1 -a "$1" == --help ] && exit_with uecho "$scriptname: wrapper autour de awk pour rechercher des lignes d'un fichier csv +${Clang:+note: ce script ne tient pas compte de la locale: il travaille avec LANG=C +} +USAGE + $scriptname EXPR [inputfiles...] [-- headers...] + +$__GREPCSV_HELP" + + "${prefix}grepcsv" "$@" + +elif [ "$tool" == "awkfsv2csv" ]; then + [ $# -eq 1 -a "$1" == --help ] && exit_with uecho "$scriptname: wrapper autour de awk pour transformer un fichier à colonnes fixes en fichier csv +${Clang:+note: ce script ne tient pas compte de la locale: il travaille avec LANG=C +} +USAGE + $scriptname [options] -- [header:sizes...] [-- inputfiles...] + +$__AWKFSV2CSV_HELP" + + "${prefix}awkfsv2csv" "$@" + +elif [ "$tool" == "mergecsv" ]; then + [ $# -eq 1 -a "$1" == --help ] && exit_with uecho "$scriptname: fusionner deux fichiers csv sur un champ commun +${Clang:+note: ce script ne tient pas compte de la locale: il travaille avec LANG=C +} +USAGE + $scriptname [options] left right -k field + +$__MERGECSV_HELP" + + "${prefix}mergecsv" "$@" + +elif [ "$tool" == "sortcsv" ]; then + [ $# -eq 1 -a "$1" == --help ] && exit_with uecho "$scriptname: trier un fichier csv sur un champ +${Clang:+note: ce script ne tient pas compte de la locale: il travaille avec LANG=C +} +USAGE + $scriptname [options] input -k field + +$__SORTCSV_HELP" + + "${prefix}sortcsv" "$@" + +elif [ -n "$scriptname" ]; then + die "$scriptname: nom d'outil invalide" +else + die "Vous devez spécifier l'outil à utiliser" fi From caeb06ee4a66c91bbd972cea2fc724932f9b0cdd Mon Sep 17 00:00:00 2001 From: Jephte Clain Date: Tue, 19 May 2015 18:24:41 +0400 Subject: [PATCH 2/2] =?UTF-8?q?possibilit=C3=A9=20de=20sp=C3=A9cifier=20le?= =?UTF-8?q?s=20types=20des=20champs=20pour=20mysqlloadcsv?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mysqlloadcsv | 137 +++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 112 insertions(+), 25 deletions(-) diff --git a/mysqlloadcsv b/mysqlloadcsv index d4e5392..765c51a 100755 --- a/mysqlloadcsv +++ b/mysqlloadcsv @@ -95,6 +95,11 @@ OPTIONS -z, --null-is-empty Avec les options -I et -U, considérer que NULL est représenté par la chaine vide. Cette option est équivalente à -Z '' + -t, --types [DEFAULT_TYPE,]FIELD:TYPE,... + Spécifier pour chaque champ mentionné le type de donnée à forcer. Le + type 'auto' signifie que le type est autodétecté. C'est la valeur par + défaut. Les autres types valides sont 'str', 'int' et 'date' + Cette option est ignorée avec l'option -L -A, --analyse Analyser les données et afficher une requête pour créer une table qui pourrait contenir ces données. @@ -103,6 +108,17 @@ OPTIONS APRES cette option" } +function norm_type() { + case "$1" in + string|str|s|varchar) echo varchar;; + integer|int|i) echo integer;; + #datetime|dt) echo datetime;; + date|d) echo date;; + auto|a) echo auto;; + *) echo "$1";; + esac +} + __AWK_MYSQLFUNCS=' function is_null(value) { return value == null_value @@ -127,11 +143,23 @@ function is_date(value) { } #function is_datetime(value) { #} -function format_sqlvalue(value) { - if (is_null(value)) { - value = "NULL" - } else if (is_integer(value)) { - } else if (is_date_dmy(value)) { +function format_string(value) { + gsub(/'\''/, "'\'\''", value) + value = "'\''" value "'\''" + return value +} +function format_integer(value) { + if (is_integer(value)) { + if (value != "0") { + gsub(/^0+/, "", value) + } + } else { + value = format_string(value) + } + return value +} +function format_date(value) { + if (is_date_dmy(value)) { value = "str_to_date('\''" value "'\'', '\''%d/%m/%y'\'')" } else if (is_date_dmY(value)) { value = "str_to_date('\''" value "'\'', '\''%d/%m/%Y'\'')" @@ -140,8 +168,30 @@ function format_sqlvalue(value) { } else if (is_date_Ymd2(value)) { value = "str_to_date('\''" value "'\'', '\''%Y-%m-%d'\'')" } else { - gsub(/'\''/, "'\'\''", value) - value = "'\''" value "'\''" + value = format_string(value) + } + return value +} +function format_sqlvalue(value, type) { + if (type == "varchar" || type == "string" || type == "str" || type == "s") { + value = format_string(value) + } else if (type == "integer" || type == "int" || type == "i") { + value = format_integer(value) + } else if (type == "date" || type == "d") { + value = format_date(value) + #} else if (type == "datetime" || type == "dt") { + # value = format_datetime(value) + } else { + # par defaut, autodétecter + if (is_null(value)) { + value = "NULL" + } else if (is_integer(value)) { + value = format_integer(value) + } else if (is_date(value)) { + value = format_date(value) + } else { + value = format_string(value) + } } return value } @@ -161,6 +211,7 @@ fake= method=load update_key= null_value='\N' +fieldtypes=() parse_opts "${PRETTYOPTS[@]}" \ --help '$exit_with display_help' \ -h:,-H:,--host: host= \ @@ -179,6 +230,7 @@ parse_opts "${PRETTYOPTS[@]}" \ -U:,-k:,--update-data: '$method=update; set@ update_key' \ -Z:,--null-value: null_value= \ -z,--null-is-empty null_value= \ + -t:,--types: fieldtypes \ -A,--analyse '$method=analyse; fake=1' \ @ args -- "$@" && set -- "${args[@]}" || die "$args" @@ -236,6 +288,34 @@ else cfields="$(array_join fields ,)" fi +# calculer les types à utiliser pour chaque champ +types=() +for field in "${fields[@]}"; do + array_add types "" +done +default_type=auto +array_fix_paths fieldtypes , +for ft in "${fieldtypes[@]}"; do + splitpair "$ft" f t + if [ -n "$t" ]; then + let i=0 + for field in "${fields[@]}"; do + if [ "$field" == "$f" ]; then + types[$i]="$(norm_type "$t")" + break + fi + let i=$i+1 + done + else + default_type="$(norm_type "$f")" + fi +done +let i=0 +for type in "${types[@]}"; do + [ -n "$type" ] || types[$i]="$default_type" + let i=$i+1 +done + mysqlargs=( ${host:+-h "$host"} ${port:+-P "$port"} ${user:+-u "$user"} ${database:+-D "$database"} @@ -271,7 +351,7 @@ elif [ "$method" == insert ]; then ac_set_tmpfile inserts [ -n "$truncate" ] && echo "$truncate" >>"$inserts" awkcsv <"$input" >>"$inserts" -s "$skip_lines" -v table="$table" \ - -v null_value="$null_value" -a "$__AWK_MYSQLFUNCS"'{ + -v null_value="$null_value" -v types[@] -a "$__AWK_MYSQLFUNCS"'{ count = length(ORIGHEADERS) fields = "" for (i = 1; i <= count; i++) { @@ -281,7 +361,7 @@ elif [ "$method" == insert ]; then values = "" for (i = 1; i <= count; i++) { if (i > 1) values = values ", " - values = values format_sqlvalue($i) + values = values format_sqlvalue($i, types[i]) } print "insert into `" table "` (" fields ") values (" values ");" } @@ -305,13 +385,13 @@ elif [ "$method" == update ]; then [ -n "$truncate" ] && echo "$truncate" >>"$updates" awkcsv <"$input" >>"$updates" -s "$skip_lines" \ -v table="$table" -v update_key="$update_key" \ - -v null_value="$null_value" -a "$__AWK_MYSQLFUNCS"'{ + -v null_value="$null_value" -v types[@] -a "$__AWK_MYSQLFUNCS"'{ set_values = "" cond = "" count = length(ORIGHEADERS) for (i = 1; i <= count; i++) { field = ORIGHEADERS[i] - value = format_sqlvalue($i) + value = format_sqlvalue($i, types[i]) if (field == update_key) { cond = "`" field "`=" value } else { @@ -337,21 +417,27 @@ END { elif [ "$method" == analyse ]; then ac_set_tmpfile create awkcsv <"$input" >"$create" -s "$skip_lines" -v table="$table" \ - -v null_value="$null_value" -a "$__AWK_MYSQLFUNCS"' + -v null_value="$null_value" -v types[@] -a "$__AWK_MYSQLFUNCS"' function set_integer(i) { - if (COL_TYPES[i] == "") { + if (COL_TYPES[i] == "" || COL_TYPES[i] == "integer") { COL_TYPES[i] = "integer" + return 1 } + return 0 } function set_datetime(i) { - if (COL_TYPES[i] == "") { + if (COL_TYPES[i] == "" || COL_TYPES[i] == "datetime") { COL_TYPES[i] = "datetime" + return 1 } + return 0 } function set_date(i) { - if (COL_TYPES[i] == "") { + if (COL_TYPES[i] == "" || COL_TYPES[i] == "date") { COL_TYPES[i] = "date" + return 1 } + return 0 } function set_varchar(i, col_size) { COL_TYPES[i] = "varchar" @@ -360,24 +446,25 @@ function set_varchar(i, col_size) { } else if (col_size > COL_SIZES[i]) { COL_SIZES[i] = col_size } + return 1 } { if (do_once("init")) { count = length(ORIGHEADERS) array_newsize(COL_TYPES, count) array_newsize(COL_SIZES, count) + for (i = 1; i <= count; i++) { + if (types[i] != "auto") { + COL_TYPES[i] = types[i] + } + } } for (i = 1; i <= count; i++) { - if (is_null($i)) { - } else if (is_integer($i)) { - set_integer(i) -# } else if (is_datetime($i)) { -# set_datetime(i) - } else if (is_date($i)) { - set_date(i) - } else { - set_varchar(i, length($i)) - } + if (is_null($i)) continue + if (is_integer($i) && set_integer(i)) continue +# if (is_datetime($i) && set_datetime(i)) continue + if (is_date($i) && set_date(i)) continue + set_varchar(i, length($i)) } } END {