Manipulation de chaine en bash
Affectation variable (bash ou ligne de commande)
# affectation d'une defaultvalue dans un shell var=${parameter:-defaultValue} # en shell u=${1:-root} # on peut aussi affecter une valeure par defaut avec := # mais cela ne fonctionne pas dans une fonction args() { v=${1:=one}; echo "$v"; } args -bash: $1: cannot assign in this way # alors que l'opertateur :- fonctionne args() { v=${1:-one}; echo "$v"; } args one # on peut aussi affecter une autre variable echo ${USER:-value} echo ${USER:-$truc}
source : https://www.cyberciti.biz/tips/bash-shell-parameter-substitution-2.html
Transformation d'une chaine en minuscule ou majuscule
- plusieurs solutions en bash : tr, sed, awk, ect...
- ou, sans outil supplémentaire :
# transformation en minuscule ou majuscule $var = "ToTo" echo ${var} # premiere lette en minuscule echo ${var,} toTo # toute la chaine en minuscule echo ${var,,} toto # même chose en majuscule echo ${var^} ToTo echo ${var^^} TOTO # creation de lien (en minuscule) depuis repertoire (en majuscule) for i in $(ls);do ln -s $i ${i,,};done
Spliter une chaine de caractères en tableau
distro='fedora-29-x86' # création d'un tableau avec split sur '-' IFS=\- tab=($distro) # tous les éléments du tableau echo "${tab[@]}" # accés à un élément du tableau arch=$(echo "${tab[2]}")
Manipulaion de chaines et decoupage d'URL
Bash fournit un ensemble de facilités pour manipuler les chaînes de caractères sans devoir recourir aux outils classiques tels que cut
, sed
, grep
etc.
Je parle de facilités car ce ne sont pas des fonctions ou des commandes. Ces manipulations se font via l’expansion des paramètres shell.
Nbre de caracteres d'une chaine
variable='Frédéric' echo ${#variable} 8
Remplacement de caractère
${variable:debut:longueur} variable='Frédéric' echo {variable:0:5} Frédé # attention espace obligatoire avant le -4 echo {variable: -4} éric
Autre méthode genre sed...
x='Utiliser Unix sinon rien' echo ${x/Unix/Linux} Utiliser Linux sinon rien echo ${x/Unix*/Linux} Utiliser Linux
Extraction par motif
Bash permet de supprimer des caractères d’une chaîne en se basant sur des motifs semblables à ceux utilisés pour désigner des fichiers sur la ligne de commande.
Les quatres formes sont les suivantes :
${variable#motif} ${variable##motif} ${variable%motif} ${variable%%motif}
#
et ##
permettent de supprimer un motif en début de chaîne tandis que %
et %%
permettent de supprimer un motif en fin de chaîne. La différence entre les simples et les doubles tient dans le fait que les simples suppriment le plus petit morceau de chaîne possible alors que les doubles suppriment le plus grand morceau de chaîne possible.
Quelques exemples :
variable='www.example.com/chemin/vers/ressource' ${variable#*/} → chemin/vers/ressource ${variable##*/} → ressource ${variable%/*} → www.example.com/chemin/vers ${variable%%/*} → www.example.com
On s’aperçoit immédiatement qu’il est ainsi très simple de couper une chaîne en deux par rapport à un séparateur :
variable='www.example.com/chemin/vers/ressource' ${variable%%/*} → www.example.com ${variable#*/} → chemin/vers/ressource
Par exemple, si on veut découper une URL en Bash
url='http://www.example.com:8080/chemin/vers/ressource' hostportpath="${url#http://}" → www.example.com:8080/chemin/vers/ressource path="${hostportpath#*/}" → chemin/vers/ressource hostport="${hostportpath%%/*}" → www.example.com:8080 host="${hostport%:*}" → www.example.com port="${hostport#*:}" → 808
Note : cette technique ne peut s’appliquer que pour des chaînes construites simples, dans le cas des URL elle n’est pas adaptée si on veut gérer toutes les variantes possibles.
Selection par contenu d'une variable
#si '${repodata} contient 'x86_64' if [[ "${repodata}" =~ "x86_64" ]]; then echo "arch=x86_64" else if [ $(find ${repodata} -type f -name *x86_64.rpm|wc -l) -gt 0 ]; then echo "arch=x86_64" else echo "arch=i386" fi fi
Merci : http://ouep.eu/shell/bashwget-une-pale-copie-de-wget/
Les options du shell :
# affiche options disponibles et leu état set -o # plantage d'un script si variable non initialisée set -u # NB : evite de tester si variable initialisée genre if [ "$test" == "" ]; then echo "On peut voir ainsi qu'une variable n'est pas initialisée"; fi # sortie du script à la première erreur dans le cas d'enchainement de commande set -e
${parameter:-defaultValue} | Get default shell variables value |
${parameter:=defaultValue} | Set default shell variables value |
${parameter:?"Error Message"} | Display an error message if parameter is not set |
${#var} | Find the length of the string |
${var%pattern} | Remove from shortest rear (end) pattern |
${var%%pattern} | Remove from longest rear (end) pattern |
${var:num1:num2} | Substring |
${var#pattern} | Remove from shortest front pattern |
${var##pattern} | Remove from longest front pattern |
${var/pattern/string} | Find and replace (only replace first occurrence) |
${var//pattern/string} | Find and replace all occurrences |
${!prefix*} | Expands to the names of variables whose names begin with prefix. |
${var,} ${var,pattern} |
Convert first character to lowercase. |
${var,,} ${var,,pattern} |
Convert all characters to lowercase. |
${var^} ${var^pattern} |
Convert first character to uppercase. |
${var^^} ${var^^pattern} |
Convert all character to uppercase.. |
Tableau simple en bash :
# definition du tableau tab=() val1='ma-premiere-valeure' val2='ma-deuxieme-valeure' # ajout dans le tableau tab+=($val1) tab+=($val2) # accés au tableau # premier element echo $tab # tout le tableau echo ${tab[*]} # boucle sur le tableau for t in ${tab[*]} do echo ${t} done