##@cooked comments # -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8 ## Fonctions de base: gestion des valeurs scalaires ##@cooked nocomments # Note: contient du code spécifique à bash 4. Le module base.compat réimplémente # les fonctions concernées pour les rendre compatible avec bash >= 2.x uprovide base.string urequire base.core # IMPORTANT: aucune des fonctions suivantes ne met en échappement les valeur des # patterns. Ainsi, si un pattern contient des caractères interdits comme \ ou $, # il faut d'abord le traiter avec _qval() function straddp() { # ajouter le préfixe $1 à $2* local p="$1"; shift echo "$p$*" } function strdelp() { # enlever le préfixe $1 à $2* local p="$1"; shift local str="$*" echo "${str#$p}" } function strdelp2() { # enlever le préfixe $1 le plus long à $2* local p="$1"; shift local str="$*" echo "${str##$p}" } function stradds() { # ajouter le suffixe $1 à $2* local s="$1"; shift echo "$*$s" } function strdels() { # enlever le suffixe $1 à $2* local s="$1"; shift local str="$*" echo "${str%$s}" } function strdels2() { # enlever le suffixe le plus long $1 à $2* local s="$1"; shift local str="$*" echo "${str%%$s}" } function strlower() { # afficher en minuscule la valeur $* local str="$*" echo "${str,,}" } function strlower1() { # afficher la valeur $* après avoir converti la première lettre en minuscule local str="$*" echo "${str,}" } function strlowers() { # afficher les valeurs $1..* après avoir converti leur première lettre en # minuscule local str="$*" echo "${*,}" } function strupper() { # afficher en majuscule la valeur $* local str="$*" echo "${str^^}" } function strupper1() { # afficher la valeur $* après avoir converti la première lettre en majuscule local str="$*" echo "${str^}" } function struppers() { # afficher les valeurs $1..* après avoir converti leur première lettre en # majuscule echo "${*^}" } function strmid() { # Afficher la plage $1 de la valeur $2*. La plage peut être d'une des formes # 'start', '[start]:length'. Si start est négatif, le compte est effectué à # partir de la fin de la chaine. Si length est négatif, il est rajouté à la # longueur de la chaine à partir de start local range="$1"; shift local str="$*" if [[ "$range" == *:-* ]]; then local max=${#str} [ $max -eq 0 ] && return local start="${range%%:*}" [ -n "$start" ] || start=0 while [ "$start" -lt 0 ]; do start=$(($max$start)) done max=$(($max-$start)) local length="${range#*:}" while [ "$length" -lt 0 ]; do length=$(($max$length)) done range="$start:$length" fi eval 'echo "${str:'" $range"'}"' } function strrepl() { # Remplacer dans la valeur $3* le motif $1 par la chaine $2. $1 peut commencer # par l'un des caractères /, #, % pour indiquer le type de recherche local pattern="$1"; shift local repl="$1"; shift local str="$*" local cmd='echo "${str/' if [ "${pattern#/}" != "$pattern" ]; then pattern="${pattern#/}" cmd="$cmd/" elif [ "${pattern#\#}" != "$pattern" ]; then pattern="${pattern#\#}" cmd="$cmd#" elif [ "${pattern#%}" != "$pattern" ]; then pattern="${pattern#%}" cmd="$cmd%" fi cmd="$cmd"'$pattern/$repl}"' eval "$cmd" } function strops() { # Appliquer à une chaine de caractères une suite de traitements, e.g: # 'strops var deref +suffix' est équivalent à 'echo "${var}suffix"' # En commençant avec la valeur initiale $1, les arguments $2..* sont des # opérations à appliquer dans l'ordre. # Les opérations suivantes considèrent que la valeur courante est un nom de # variable: # :- := :? :+ deref dcount # Toutes les autres opérations travaillent directement avec la valeur # courante. Les opérations suivantes appliquent une transformation: # # % / : ^ , +# -# +% -% + - mid repl # Les opérations suivantes font un test sur la valeur et retournent # immédiatement: # = == != < > -eq -ne -lt -le -gt -ge -n -z # La syntaxe des opérateurs standards de bash est reprise autant que possible, # i.e si on a l'habitude d'écrire ${varOP} en bash, alors la syntaxe à utiliser # à priori est 'strops var OP' ou 'strop var deref OP' suivant les opérateurs. # Autres opérateurs: # deref indirection # dcount nombre d'éléments du tableau # +#STR ajouter un préfixe # -#STR supprimer un préfixe # +%STR ou +STR ajouter un suffixe # -%STR ou -STR supprimer un suffixe # mid RANGE traiter la chaine avec strmid() # repl FROM TO traiter la chaine avec strrepl() local -a __s_tmp local __s_value="$1"; shift while [ $# -gt 0 ]; do case "$1" in # l'argument est le nom de la variable :-*|:=*|:\?*|:+*) eval '__s_value="${'"${__s_value}$1"'}"';; d|deref) __s_value="${!__s_value}";; dc|dcount|ds|dsize) __s_value="${__s_value}[@]" __s_tmp=("${!__s_value}") __s_value="${#__s_tmp[@]}" ;; # l'argument est la valeur de la variable \#*|%*|/*|:*|^*|,*) eval '__s_value="${__s_value'"$1"'}"';; l|length) __s_value="${#__s_value}";; =|==|!=|\<|\>|-eq|-ne|-lt|-le|-gt|-ge) __s_tmp=(\[ "$__s_value" "$@" ]); "${__s_tmp[@]}"; return $?;; -n|-z) __s_tmp=(\[ "$1" "$__s_value" ]); "${__s_tmp[@]}"; return $?;; +#*) eval '__s_value="'"${1#+#}"'$__s_value"';; -#*) eval '__s_value="${__s_value'"${1#-}"'}"';; +%*) eval '__s_value="$__s_value"'"${1#+%}";; +*) eval '__s_value="$__s_value"'"${1#+}";; -%*) eval '__s_value="${__s_value'"${1#-}"'}"';; -*) eval '__s_value="${__s_value%'"${1#-}"'}"';; mid|strmid) eval '__s_value="$(strmid "$2" "$__s_value")"'; shift;; repl|strrepl) eval '__s_value="$(strrepl "$2" "$3" "$__s_value")"'; shift; shift;; *) echo 1>&2 "strops: unknown operator: $1";; esac shift done echo "$__s_value" } function first_char() { # retourner le premier caractère de la chaine $* local str="$*" echo "${str:0:1}" } function last_char() { # retourner le dernier caractère de la chaine $* local str="$*" echo "${str: -1:1}" } function first_chars() { # retourner tous les caractères de la chaine $*, excepté le dernier local str="$*" recho "${str:0:$((${#1}-1))}" } function last_chars() { # retourner tous les caractères de la chaine $*, excepté le premier local str="$*" recho "${str:1}" } function first_char_is() { # Tester si le premier caractère de la chaine $1 est $2 [ "${1:0:1}" == "$2" ] } function last_char_is() { # Tester si le dernier caractère de la chaine $1 est $2 [ "${1:$((-1)):1}" == "$2" ] } function beginswith() { # Tester si la chaine $1 commence par le wildcard $2 local str="$1" pattern="$2" eval '[ "${str#$pattern}" != "$str" ]' } function endswith() { # Tester si la chaine $1 se termine par le wildcard $2 local str="$1" pattern="$2" eval '[ "${str%$pattern}" != "$str" ]' }