diff --git a/CHANGES.txt b/CHANGES.txt index af73223..cff3666 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,3 +1,19 @@ +## Version 4.0.0 du 01/03/2016-19:08 + +c46626c ldif: support de dumpcsv et printcsv dans get_transform_cmd() +d661e43 doinplace fonctionne comme la fonction. la version étendue est un lien nommé doinplacex +d6540ac dumpcsv: ajouter l'option --hname +903d500 dumpcsv: ajouter les options --keep-fields, --skip-fields, --dump-headers +af18332 implémenter printcsv +383410a *csv: améliorer cohérences des arguments +4808fa0 dumpcsv: ajout de l'option -b +939b5ad implémenter dumpcsv et nettoyer un peu le code +cb0e553 script doinplace qui mélange les fonctionnalités des fonctions doinplace et evalp +0cf8e04 scripts noerror, noout, noerr qui fonctionnent comme les fonctions du même nom +66249c9 nutools base: ajout de noerror(), noout(), noerr() +db76488 maj doc +40f1bf6 prel: après avoir fusionné une branche, revenir sur develop + ## Version 3.5.0 du 26/02/2016-11:35 4648b3f awkrun: ajout de la fonction qarr() diff --git a/VERSION.txt b/VERSION.txt index 1545d96..fcdb2e1 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -3.5.0 +4.0.0 diff --git a/doinplace b/doinplace new file mode 100755 index 0000000..4087def --- /dev/null +++ b/doinplace @@ -0,0 +1,74 @@ +#!/bin/bash +# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8 + +TOOLS=(doinplacef doinplacex) +if [ "$#" -eq 1 -a "$1" == --nutools-makelinks ]; then + # créer les liens + scriptname="$(basename "$0")" + for tool in "${TOOLS[@]}"; do + ln -s "$scriptname" "$tool" + done + exit 0 +fi + +source "$(dirname "$0")/lib/ulib/ulib" || exit 1 +urequire base + +function display_help() { + uecho "$scriptname: filtrer en place un fichier à travers une suite de commandes + +USAGE + $scriptname FILE COMMAND [ARGS...] + +Si on utilise une commande avec des options, penser à utliser '--' pour séparer +les options de ce script des options de la commande + +En plus des commandes systèmes, il est possible d'utiliser toute fonction de +nutools qui effectue des traitement sur un flux comme stripnl, filter_empty, +merge_contlines, filter_comment, filter_conf, etc. Les fonctions nl2lf, nl2crlf, +nl2cr, latin1compat et noaccents sont aussi disponibles par convenance. + +OPTIONS + -p, --evalp + Evaluer la commande avec evalp(), ce qui permet de chainer plusieurs + commandes en les séparant par //. Cette option est automatiquement + activée si ce script est lancé avec le nom doinplacex + -g, --ignore-error, --replace-always + Normalement, le fichier n'est pas remplacé si la commande retourne une + erreur. Avec cette option, le fichier est remplacé quel que soit le code + de retour de la commande. A utiliser par exemple avec des commandes + comme grep qui peuvent retourner FAUX s'ils ne trouvent pas le motif. + Cette option est automatiquement activée si ce script est lancé avec le + nom doinplacef" +} + +function nl2lf() { _nl2lf; } +function nl2crlf() { _nl2crlf; } +function nl2cr() { _nl2cr; } +function latin1compat() { _latin1compat; } +function noaccents() { _noaccents; } + +[ "$scriptname" == doinplacex ] && evalp=1 || evalp= +[ "$scriptname" == doinplacef ] && replace=1 || replace= +args=( + --help '$exit_with display_help' + -p,--evalp evalp=1 + -g,--ignore-error,--replace-always replace=1 +) +parse_args "$@"; set -- "${args[@]}" + +file="$1"; shift +if [ -n "$evalp" ]; then + if [ -n "$replace" ]; then + doinplacef "$file" evalp "$@" + else + doinplace "$file" evalp "$@" + fi +else + if [ -n "$replace" ]; then + doinplacef "$file" "$@" + else + doinplace "$file" "$@" + fi +fi +exit $? diff --git a/fconv b/fconv index b1c603f..58e2025 100755 --- a/fconv +++ b/fconv @@ -10,7 +10,7 @@ USAGE $scriptname -f FILE [cmds...] $scriptname FILE [cmds...] -Une ou plusieurs commandes peuvent être spécifiées, séparées // +Une ou plusieurs commandes peuvent être spécifiées, séparées par // La commande par défaut est 'lf' Si des commandes utilisant des options sont utilisées, penser à séparer les options de $scriptname avec -- diff --git a/lib/uinst/conf b/lib/uinst/conf index 7368b8a..a6addb0 100644 --- a/lib/uinst/conf +++ b/lib/uinst/conf @@ -32,6 +32,7 @@ done ./uawk --nutools-makelinks ./udist --nutools-makelinks ./ulink --nutools-makelinks +./doinplace --nutools-makelinks # complétion programmable rm -f ~/etc/bashrc.d/bash_completion.nutools # renommé diff --git a/lib/ulib/.ulibver b/lib/ulib/.ulibver index 9aa1097..f833300 100644 --- a/lib/ulib/.ulibver +++ b/lib/ulib/.ulibver @@ -1 +1 @@ -011003000 +012000000 diff --git a/lib/ulib/awk b/lib/ulib/awk index e88e78c..d224539 100644 --- a/lib/ulib/awk +++ b/lib/ulib/awk @@ -72,9 +72,12 @@ sqvals(s) print \"mycmd\" sqvals() L'alias qsvals(s) existe pour compatibilité -qarr(vs) +qarr(vs[, prefix]) quoter les valeurs du tableau vs pour le shell, e.g: print \"values=(\" qarr(values) \")\" + si prefix est spécifié, il est affiché suivi d'un espace, suivi des valeurs + du tableau, ce qui permet de construire une ligne de commande, e.g.: + print qarr(values, \"mycmd\") qsubrepl(s) quoter une valeur pour l'argument r des fonctions sub() et gsub(). Les @@ -306,9 +309,9 @@ données, e.g: pour mettre en majuscule le deuxième champ. Analyse du flux en entrée: --s, --skip-lines nblines +-s, -S, --skip-lines nblines Sauter nblines au début du flux --h, --parse-headers +-h, -H, --parse-headers Lire la liste des champs à partir de la première ligne non ignorée du flux. Si la liste des champs est vide, cette option est implicitement activée. Par contre, si une liste de champs est spécifiée et que le flux en entrée @@ -379,13 +382,13 @@ Scripts: '{ if (!checkvalues(FIELDS)) exit 1 }' Ce traitement est effectué le cas échéant après le traitement --checkfields Cette option annule l'option -z --k, --keep KEEPFIELDS +-k, --keep-fields KEEPFIELDS Garder les champs spécifiés. Les autres sont supprimés de la sortie. KEEPFIELDS est une liste de champs séparés par des virgules, ou '*' pour spécifier de garder tous les champs, ou '' pour ne garder aucun champ. Si un champ de KEEPFIELDS n'existe pas, il est créé. Cette option annule l'option -z ---skip SKIPFIELDS +--skip-fields SKIPFIELDS Exclure les champs spécifiés. SKIPFIELDS est une liste de champs séparés par des virgules. Pour les options --keep et --skip, un script équivalent au suivant est @@ -735,14 +738,14 @@ function lawkcsv() { }' local -a args headers vars - local skip_lines=0 parse_headers= + local skip=0 parse_headers= local autosep= local sepconf=',"' colsep=',' qchar='"' echar= local show_headers=1 reset_fields= - local fieldmap checkfields checkvalues keepfields skipfields + local fieldmap checkfields checkvalues keepf skipf if parse_opts \ - -s:,--skip-lines: skip_lines= \ - -h,--parse-headers parse_headers=1 \ + -s:,-S:,--skip-lines:,--skiplines: skip= \ + -h,-H,--parse-headers parse_headers=1 \ --sepconf: '$autosep=sepconf; set@ sepconf' \ --colsep: '$autosep=indiv; set@ colsep' \ --qchar: '$autosep=indiv; set@ qchar' \ @@ -756,10 +759,10 @@ function lawkcsv() { --re: '$set@ awkscript; append_awkscript=' \ -e:,--e:,--awk-script:,--script: append_awkscript= \ -m:,--map:,--mapfields fieldmap= \ - -c:,--checkfields: checkfields= \ - --checkvalues: checkvalues= \ - -k:,--keep:,--keepfields: keepfields= \ - --skip:,--skipfields: skipfields= \ + -c:,--check-fields:,--checkfields: checkfields= \ + --check-values:,--checkvalues: checkvalues= \ + -k:,--keep:,--keep-fields:,--keepfields: keepf= \ + --skip:,--skip-fields:,--skipfields: skipf= \ --ra:,--rae: '$set@ afterscript; append_afterscript=' \ -a:,--a:,--ae:,--after-script: append_afterscript= \ @ args -- "$@"; then @@ -815,10 +818,10 @@ function lawkcsv() { }' reset_fields= fi - if [ -n "$skipfields" ]; then - [ -n "$keepfields" ] || keepfields="*" + if [ -n "$skipf" ]; then + [ -n "$keepf" ] || keepf="*" fi - if [ -n "$keepfields" ]; then + if [ -n "$keepf" ]; then awkscript="$awkscript"'{ if (do_once("filterfields")) { build_skipfs(fields2keep, fields2skip, SKIPFS, ADDFS) @@ -830,11 +833,11 @@ function lawkcsv() { fi awkrun -f \ - skip_lines:int="$skip_lines" parse_headers:int="$parse_headers" \ + skip_lines:int="$skip" parse_headers:int="$parse_headers" \ autosep:int="$autosep" colsep="$colsep" qchar="$qchar" echar="$echar" \ show_headers:int="$show_headers" reset_fields:int="$reset_fields" \ fields2map="$fieldmap" fields2check="$checkfields" values2check="$checkvalues" \ - fields2keep="$keepfields" fields2skip="$skipfields" \ + fields2keep="$keepf" fields2skip="$skipf" \ "user_headers[@]=headers" "${vars[@]}" \ "$__AWKCSV_FUNCTIONS"' BEGIN { @@ -865,9 +868,9 @@ correspondent à l'expression. EXPR est une expression awk, e.g. 'field == \"value1\" || field == \"value2\"' Analyse du flux en entrée: --s, --skip-lines nblines +-s, -S, --skip-lines nblines Sauter nblines au début du flux --h, --parse-headers +-h, -H, --parse-headers Lire la liste des champs à partir de la première ligne non ignorée du flux. Si la liste des champs est vide, cette option est implicitement activée. Par contre, si une liste de champs est spécifiée et que le flux en entrée @@ -914,14 +917,14 @@ Scripts: function lgrepcsv() { local -a args vars - local skip_lines= parse_headers= + local skip= parse_headers= local sepconf= colsep= qchar= echar= local no_headers= quiet= local awkscript=--use-default-- local append_awkscript= if parse_opts \ - -s:,--skip-lines: skip_lines= \ - -h,--parse-headers parse_headers=1 \ + -s:,-S:,--skip:,--skip-lines:,--skiplines: skip= \ + -h,-H,--parse-headers parse_headers=1 \ --sepconf: sepconf= \ --colsep: colsep= \ --qchar: qchar= \ @@ -966,7 +969,7 @@ function lgrepcsv() { headers=("$@") if [ -z "${headers[*]}" ]; then parse_headers=1 - array_from_lines headers "$(awkrun -f lskip:int="$skip_lines" 'NR <= lskip { next } + array_from_lines headers "$(awkrun -f lskip:int="$skip" 'NR <= lskip { next } { count = array_parsecsv(__fields, $0) for (i = 1; i <= count; i++) { @@ -996,7 +999,7 @@ BEGIN { ec = 1 } } END { exit ec }" - lawkcsv ${skip_lines:+-s "$skip_lines"} ${parse_headers:+-h} \ + lawkcsv ${skip:+-s "$skip"} ${parse_headers:+-h} \ ${sepconf:+--sepconf "$sepconf"} ${colsep:+--colsep "$colsep"} ${qchar:+--qchar "$qchar"} ${echar:+--echar "$echar"} \ ${no_headers:+--no-headers} -v quiet:int=$quiet \ --re '{array_parsecsv(ORIGFIELDS, $0, array_len(ORIGHEADERS))}' -a "$grepscript" \ @@ -1019,7 +1022,7 @@ Chaque argument doit être de la forme [-]header:size. La colonne sera incluse dans le fichier en sortie, sauf si elle est précédée de - Analyse du flux en entrée: --s, --skip-lines nblines +-s, -S, --skip-lines nblines Sauter nblines au début du flux -r, --no-trim Ne pas trimmer les valeurs à droite. @@ -1030,10 +1033,10 @@ Flux en sortie: function lawkfsv2csv() { local -a args headersizes - local skip_lines=0 trim_values=1 show_headers=1 + local skip=0 rtrim=1 show_headers=1 if parse_opts \ - -s:,--skip-lines: skip_lines= \ - -r,--no-trim trim_values= \ + -s:,-S:,--skip:,--skip-lines:,--skiplines: skip= \ + -r,--no-trim rtrim= \ -n,--no-headers show_headers= \ --show-headers show_headers=1 \ @ args -- "$@"; then @@ -1066,7 +1069,7 @@ function lawkfsv2csv() { shift awkrun -f \ - skip_lines:int="$skip_lines" trim_values:int="$trim_values" show_headers:int="$show_headers" \ + skip_lines:int="$skip" trim_values:int="$rtrim" show_headers:int="$show_headers" \ headers[@] starts[@] sizes[@] \ "$__AWKCSV_FUNCTIONS"' BEGIN { @@ -1101,12 +1104,12 @@ __MERGECSV_HELP="\ Fusionner deux fichiers csv en faisant la correspondance sur la valeur d'un champ, qui est la clé --h, --parse-headers +-h, -H, --parse-headers Lire la liste des champs à partir de la première ligne non ignorée des flux. Si cette option est spécifiée (ce qui est le cas par défaut), les champs spécifiés avec les options -k, --lk et --rk peuvent être les noms effectifs des champs. Sinon, les champs ne peuvent être que numériques. --n, --numkeys +-n, -N, --numkeys Ne pas analyser la première ligne pour les noms des champs. Les champs spécifiés ne peuvent être que numériques. --lskip nblines @@ -1215,8 +1218,8 @@ function lmergecsv() { local lkeepf=--NOT-SET-- rkeepf=--NOT-SET-- local lskipf= rskipf= parse_opts "${PRETTYOPTS[@]}" \ - -h,--parse-headers parse_headers=1 \ - -n,--numkeys parse_headers= \ + -h,-H,--parse-headers parse_headers=1 \ + -n,-N,--numkeys parse_headers= \ --lskip: lskip= \ --lkey:,--lk: lkey= \ --lheaders:,--lh: lheaders= \ @@ -1609,14 +1612,14 @@ function mergecsv() { LANG=C lmergecsv "$@"; } __SORTCSV_HELP="\ Trier un fichier csv sur la valeur d'un champ ---skip nblines +-S, --skip-lines nblines Sauter nblines au début du flux --h, --parse-headers +-h, -H, --parse-headers Lire la liste des champs à partir de la première ligne non ignorée des flux. Si cette option est spécifiée (ce qui est le cas par défaut), le champ spécifié avec l'option -k peut être le nom effectif du champ. Sinon, le champ ne peut être que numérique. ---numkeys +-N, --numkeys Ne pas analyser la première ligne pour les noms des champs. Les champs spécifiés ne peuvent être que numériques. -k, --key FIELD @@ -1649,9 +1652,9 @@ function lsortcsv() { local skip=0 parse_headers=auto key=1 show_headers=1 local numeric_sort= ignore_case= reverse_sort= stable_sort= unique_sort= output= parse_opts "${PRETTYOPTS[@]}" \ - --skip: skip= \ - -h,--parse-headers parse_headers=1 \ - --numkeys parse_headers= \ + -S:,--skip:,--skip-lines:,--skiplines: skip= \ + -h,-H,--parse-headers parse_headers=1 \ + -N,--numkeys parse_headers= \ -k:,--key: key= \ --no-headers show_headers= \ --show-headers show_headers=1 \ @@ -1742,3 +1745,190 @@ BEGIN { if (show_headers) print headerscsv } function csortcsv() { LANG=C lsortcsv "$@"; } function sortcsv() { LANG=C lsortcsv "$@"; } + +################################################################################ + +__DUMPCSV_HELP="\ +Afficher les champs spécifiés pour traitement par le shell + +-S, --skip-lines nblines + Sauter nblines au début du flux +-H, --parse-headers + Lire la liste des champs à partir de la première ligne non ignorée du flux. + Si cette option est spécifiée (ce qui est le cas par défaut), les champs + spécifiés peuvent être les noms effectifs des champs. Sinon, les champs ne + peuvent être que numériques. +-N, --numkeys + Ne pas analyser la première ligne pour les noms des champs. Les champs + spécifiés ne peuvent être que numériques. + +-k, --keep-fields KEEPFIELDS + Garder les champs spécifiés. Les autres sont supprimés de la sortie. + KEEPFIELDS est une liste de champs séparés par des virgules. +-s, --skip-fields SKIPFIELDS + Exclure les champs spécifiés. SKIPFIELDS est une liste de champs séparés par + des virgules. + +-h, --dump-headers + Inclure les en-têtes dans la sortie. Elles sont traitées exactement comme + une ligne de données. +--hname HNAME + 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 +-f, --function + Afficher les champs comme l'appel d'une fonction, e.g: + dump value00 value01... + dump value10 value11... + C'est la méthode d'affichage par défaut. 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' +-a, --array + Afficher les champs comme les valeurs d'un tableau, e.g: + values=(value00 value01...) + values=(value10 value11...) + L'option -n permet de spécifier le nom du tableau, qui vaut 'values' par + défaut. Avec -h, le nom par défaut est 'names' +-b, --array-function + Afficher les champs comme l'initialisation des valeurs d'un tableau suivi de + l'appel d'une fonction, e.g: + values=(value00 value01...) + dump + values=(value10 value11...) + dump + 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'" + +function ldumpcsv() { + eval "$(utools_local)" + local skip= parse_headers=1 keepf skipf show_headers + local dump=function name hname + parse_opts "${PRETTYOPTS[@]}" \ + -S:,--skip:,--skip-lines:,--skiplines: skip= \ + -H,--parse-headers parse_headers=1 \ + -N,--numkeys parse_headers= \ + -k:,--keep:,--keep-fields:,--keepfields: keepf= \ + -s:,--skip:,--skip-fields:,--skipfields: skipf= \ + -h,--dump-headers show_headers=1 \ + -n:,--name: name= \ + --hname: hname= \ + -f,--function dump=function \ + -a,--array dump=array \ + -b,--array-function dump=array-function \ + @ args -- "$@" && set -- "${args[@]}" || die "$args" + + args=( + ${skip:+--skip-lines "$skip"} + ${keepf:+--keep-fields "$keepf"} + ${skipf:+--skip-fields "$skipf"} + ) + if [ -n "$parse_headers" ]; then array_add args -h + else array_add args -n + fi + + if [ -z "$hname" ]; then + case "$dump" in + function|array-function) hname=dumph;; + array) hname=names;; + esac + fi + if [ -z "$name" ]; then + case "$dump" in + function|array-function) name=dump;; + array) name=values;; + esac + fi + + local -a fields + fields=("$@") + + awkcsv "${args[@]}" -v show_headers:int="$show_headers" -v hname="$hname" -v name="$name" -v dump="$dump" -v fields[@] -e ' +function dump_values(name, values) { + if (dump == "function") { + print qarr(values, name) + } else if (dump == "array") { + print name "=(" qarr(values) ")" + } else if (dump == "array-function") { + print "values=(" qarr(values) ")" + print name + } +} +{ + if (do_once("init_fields")) { + if (fields_count == 0) { + array_copy(fields, HEADERS) + fields_count = array_len(fields) + } + if (show_headers) { + dump_values(hname, fields) + } + } + array_new(values) + i = 1 + while (i <= fields_count) { + values[i] = get(fields[i]) + i++ + } + dump_values(name, values) +}' -a '' +} + +function cdumpcsv() { LANG=C ldumpcsv "$@"; } +function dumpcsv() { LANG=C ldumpcsv "$@"; } + +################################################################################ + +__PRINTCSV_HELP="\ +Afficher les valeurs spécifiées au format CSV + +-F, --fields FIELDS + Spécifier les champs en sortie +-o, --output OUTPUT + Ajouter la ligne au fichier spécifié. Si le fichier n'existe pas ou est de + taille vide, et que l'option -F est spécifiée, alors écrire les en-têtes + dans le fichier avant d'écrire les valeurs. +--show-headers +-n, --no-headers + Forcer l'affichage (resp. le non-affichage) des en-têtes" + +function lprintcsv() { + eval "$(utools_local)" + local fields output show_headers=auto + parse_opts "${PRETTYOPTS[@]}" \ + -F:,--fields: fields= \ + -o:,--output: output= \ + -n,--no-headers show_headers= \ + --show-headers show_headers=1 \ + @ args -- "$@" && set -- "${args[@]}" || die "$args" + + array_split fields "$fields" , + [ "$output" == - ] && output= + [ -n "$fields" ] || show_headers= + if [ "$show_headers" == auto ]; then + if [ -n "$output" ]; then + [ -s "$output" ] || show_headers=1 + else + show_headers= + fi + fi + [ -n "$output" ] || output=/dev/stdout + values=("$@") + + awkrun -f >>"$output" fields[@] show_headers:int="$show_headers" values[@] ' +BEGIN { + if (show_headers) array_printcsv(fields) + if (fields_count > 0) count = fields_count + else count = values_count + array_new(output) + for (i = 1; i <= count; i++) { + if (i <= values_count) output[i] = values[i] + else output[i] = "" + } + array_printcsv(output) +}' +} + +function cprintcsv() { LANG=C lprintcsv "$@"; } +function printcsv() { LANG=C lprintcsv "$@"; } diff --git a/lib/ulib/base b/lib/ulib/base index 5cca546..f7aeef3 100644 --- a/lib/ulib/base +++ b/lib/ulib/base @@ -1888,11 +1888,11 @@ function qvals( i, line) { function sqvals() { return " " qvals() } -function qarr(values, i, count, line) { - line = "" +function qarr(values, prefix, i, count, line) { + line = prefix count = array_len(values) for (i = 1; i <= count; i++) { - if (i > 1) line = line " " + if (i > 1 || line != "") line = line " " line = line qval(values[i]) } return line @@ -2843,6 +2843,22 @@ function eerror_if() { fi } +function noerror() { +# lancer la commande "$@" et masquer son code de retour + [ $# -gt 0 ] || set : + "$@" || return 0 +} +function noout() { +# lancer la commande "$@" en supprimant sa sortie standard + [ $# -gt 0 ] || return 0 + "$@" >/dev/null +} +function noerr() { +# lancer la commande "$@" en supprimant sa sortie d'erreur + [ $# -gt 0 ] || return 0 + "$@" 2>/dev/null +} + TAB=$'\t' LATIN1=iso-8859-1 LATIN9=iso-8859-15 diff --git a/lib/ulib/ldif b/lib/ulib/ldif index d122438..338c818 100644 --- a/lib/ulib/ldif +++ b/lib/ulib/ldif @@ -1205,6 +1205,10 @@ mergecsv [OPTIONS] LEFT RIGHT -k FIELD $(sed 's/^/ /g' <<<"$__MERGECSV_HELP") sortcsv [OPTIONS] INPUT -k FIELD $(sed 's/^/ /g' <<<"$__SORTCSV_HELP") +dumpcsv [OPTIONS] FIELDS... +$(sed 's/^/ /g' <<<"$__DUMPCSV_HELP") +printcsv [OPTIONS] VALUES... +$(sed 's/^/ /g' <<<"$__PRINTCSV_HELP") lsed ARGS lawk ARGS @@ -1214,6 +1218,8 @@ lawkrun [ARGS] lawkcsv [OPTIONS] [ATTRS...] lmergecsv [OPTIONS] LEFT RIGHT -k FIELD lsortcsv [OPTIONS] INPUT -k FIELD +ldumpcsv [OPTIONS] FIELDS... +lprintcsv [OPTIONS] VALUES... Ces commandes sont comme les commandes sans le préfixe 'l', mais elles sont lancées sans LANG=C, ce qui fait qu'elle tiennent compte de la locale. En effet, les outils de coreutils utilisent les règles de la locale pour le @@ -1351,6 +1357,10 @@ function get_transform_cmd() { lmergecsv) cmdparts=(lmergecsv "$@");; sortcsv|csortcsv) cmdparts=(csortcsv "$@");; lsortcsv) cmdparts=(lsortcsv "$@");; + dumpcsv|cdumpcsv) cmdparts=(cdumpcsv "$@");; + ldumpcsv) cmdparts=(ldumpcsv "$@");; + printcsv|cprintcsv) cmdparts=(cprintcsv "$@");; + lprintcsv) cmdparts=(lprintcsv "$@");; f|format) cmdparts=(tl_format "$@");; fcsv|formatcsv|format_csv|csv) cmdparts=(tl_formatcsv "$@");; pcsv|parsecsv|parse_csv) cmdparts=(tl_parsecsv "$@");; diff --git a/noerr b/noerr new file mode 100755 index 0000000..195a26d --- /dev/null +++ b/noerr @@ -0,0 +1,4 @@ +#!/bin/bash +# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8 +[ $# -gt 0 ] || exit 0 +"$@" 2>/dev/null diff --git a/noerror b/noerror new file mode 100755 index 0000000..547dc1b --- /dev/null +++ b/noerror @@ -0,0 +1,4 @@ +#!/bin/bash +# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8 +[ $# -gt 0 ] || set : +"$@" || exit 0 diff --git a/noout b/noout new file mode 100755 index 0000000..8f5b5d9 --- /dev/null +++ b/noout @@ -0,0 +1,4 @@ +#!/bin/bash +# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8 +[ $# -gt 0 ] || exit 0 +"$@" >/dev/null diff --git a/prel b/prel index e446a8d..dcb590f 100755 --- a/prel +++ b/prel @@ -373,6 +373,7 @@ elif is_release_branch "$branch"; then release="$branch" fi +final_branch= # branche sur laquelle se placer après avoir fusionné la branche de release if [ "$action" == merge ]; then confirm= @@ -433,6 +434,7 @@ ou celle-ci pour pour pousser TOUS les tags: setx branch=git_get_branch action=delete + final_branch=develop fi if [ "$action" == delete -a "$release" != develop ]; then @@ -501,3 +503,8 @@ elif [ "$action" == diff ]; then fi fi fi + +# en fin de traitement, revenir le cas échéant sur $final_branch +if [ -n "$final_branch" ]; then + git checkout "$final_branch" || die +fi diff --git a/uawk b/uawk index 5ed1e50..bc3d07c 100755 --- a/uawk +++ b/uawk @@ -1,7 +1,7 @@ #!/bin/bash # -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8 -TOOLS=(awkrun awkcsv grepcsv awkfsv2csv mergecsv sortcsv) +TOOLS=(awkrun awkcsv grepcsv awkfsv2csv mergecsv sortcsv dumpcsv printcsv) if [ "$#" -eq 1 -a "$1" == --nutools-makelinks ]; then # créer les liens scriptname="$(basename "$0")" @@ -122,8 +122,31 @@ $__SORTCSV_HELP" "${prefix}sortcsv" "$@" +elif [ "$tool" == "dumpcsv" ]; then + [ $# -eq 1 -a "$1" == --help ] && exit_with uecho "$scriptname: afficher les champs d'un flux CSV pour traitement par le shell +${Clang:+note: ce script ne tient pas compte de la locale: il travaille avec LANG=C +} +USAGE + $scriptname [options] fields... + +$__DUMPCSV_HELP" + + "${prefix}dumpcsv" "$@" + +elif [ "$tool" == "printcsv" ]; then + [ $# -eq 1 -a "$1" == --help ] && exit_with uecho "$scriptname: afficher des champs au format CSV +${Clang:+note: ce script ne tient pas compte de la locale: il travaille avec LANG=C +} +USAGE + $scriptname [options] values... + +$__PRINTCSV_HELP" + + "${prefix}printcsv" "$@" + elif [ -n "$scriptname" ]; then die "$scriptname: nom d'outil invalide" + else die "Vous devez spécifier l'outil à utiliser" fi