nutools/lib/ulib/base.string

216 lines
6.9 KiB
Bash

##@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
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" ]'
}