# Chaine de caractères:



### Concaténer une chaine:

##### Opérateur +=

```bash
string="Hello, "
string+="World"

echo "$string"
Hello, World
```

##### Les chaines côte à côte:

```bash
string1="Hello, "
string2="World"
string3="$string1$string2"

echo "$string3"
Hello, World
```



### Trim une chaine:

1. sed

```bash
$ var="           Une chaine entourée d'espaces           "

$ echo "Fluctuat nec $var mergitur"
Fluctuat nec            Une chaine entourée d'espaces            mergitur

# supprimer les espaces en fin de chaine: sed 's/ *$//g'`
$ var=`echo $var | sed 's/ *$//g'`

$ echo "Fluctuat nec $var mergitur"
Fluctuat nec            Une chaine entourée d'espaces mergitur

# supprimer les espaces en début de chaine: sed 's/^ *//g'`
$ var=`echo $var | sed 's/^ *//g'`

$ echo "Fluctuat nec $var mergitur"
Fluctuat nec Une chaine entourée d'espaces mergitur

# supprimer les espaces en début et fin de chaine:

$ var="           Une chaine entourée d'espaces           "
$ echo "$var" | sed 's/^[[:blank:]]*//;s/[[:blank:]]*$//'
Une chaine entourée d'espaces
```

2. awk

```bash
$ echo "${var}"
           Une chaine entourée d'espaces

$ echo "${var}" | awk '{gsub(/^[ \t]+/,""); print $0, " fin" }'
Une chaine entourée d'espaces             fin

$ echo "${var}" | awk '{gsub(/[ \t]+$/,""); print $0, " fin" }'
           Une chaine entourée d'espaces  fin

$ echo "${var}" | awk '{gsub(/^[ \t]+| [ \t]+$/,""); print $0, " fin" }'
Une chaine entourée d'espaces  fin
```

3. xargs

```bash
$ var="           Une chaine entourée d espaces           "

$ echo "$var" | xargs
Une chaine entourée d espaces

$ echo "           Une chaine entourée d espaces           " | xargs
Une chaine entourée d espaces

# erreur si la chaine contient un apostrophe
$ echo "           Une chaine entourée d'espaces           " | xargs
xargs: unterminated quote

# dans ce cas, on utilise xargs -0
$ echo "           Une chaine entourée d'espaces           " | xargs -0
           Une chaine entourée d'espaces
```

4. 

```bash
trim () {
    read -rd '' $1 <<<"${!1}"
}

trim foo
```



### Longueur d'une chaine:

```bash
$ echo -n "Longueur de la chaine:" | wc -c
      22

$ echo "Longueur de la chaine:" | awk '{print length}'
22

$ var="Longueur de la chaine:"
$ echo ${#var}
22
```



### Sous-chaine:

https://www.gnu.org/savannah-checkouts/gnu/bash/manual/bash.html#Shell-Parameter-Expansion

```bash
$ string=abcABC123ABCabc


# ${string:position:length}

$ echo ${string:0}
abcABC123ABCabc

$ echo ${string:1}
bcABC123ABCabc

$ echo ${string:7}
23ABCabc

$ echo ${string:7:3}
23A

# Obtenir les 2 premiers caractères:
$ echo ${string:0:2}
ab
echo "$string" | awk '{print substr($0,0,2)}'
ab

# Supprimer le dernier caractère:
$ echo ${string:0:-1}
abcABC123ABCab

# Remplacer certains caractères par un autre:
$ echo ${string//[ABC]/:}
abc:::123:::abc

# Obtenir les 4 derniers caractères:
$ echo ${stringZ: -4}		# Notez l'espace
Cabc

$ echo ${string:(-4)}
Cabc

$ echo -n $string | tail -c 4

# Filename / extension

filename=$(basename "$fullfile")
extension="${filename##*.}"
filename="${filename%.*}"
```

#### Sous-chaine entre 2 caractères ()

```bash
a="not_required=('drive' 'files' 'gitea' 'home-assistant' 'homebridge' 'portainer' 'tunes' 'wg' 'www')"

z=$(echo "$a" | awk -F"=" '{split($2, arr, "[()]"); print arr[2]}')

echo "$z"
'drive' 'files' 'gitea' 'home-assistant' 'homebridge' 'portainer' 'tunes' 'wg' 'www'
```

#### Entre 2 "" (quotes)

```bash
z=$(echo "$a" | awk -F'"' '{print $2}')
```

#### Extraire une sous-chaine par un délimiteur

```bash
$ string="Portez ce vieux whisky au juge blond qui fume"


# Supprime tout jusqu'à la 1ere occurence de ' '
$ echo "${string#* }"
ce vieux whisky au juge blond qui fume

# Supprime tout jusqu'à la dernière occurence de ' '
$ echo "${string##* }"
fume

# Supprime tout après la dernière occurence de ' '
echo ${string%' '*}
Portez ce vieux whisky au juge blond qui
```



### Remplacement de sous-chaine:

```bash
$ string=abcABC123ABCabc

$ echo ${string/abc/xyz}				# Remplace la 1ere sous-chaine 'abc' par 'xyz'.
xyzABC123ABCabc

$ echo ${string//abc/xyz}   		# Remplace toutes les sous-chaine 'abc' par 'xyz'.   
xyzABC123ABCxyz

match=abc
repl=000
echo ${string/$match/$repl}
000ABC123ABCabc

echo ${string//$match/$repl}
000ABC123ABC000


echo ${stringZ/abc}           # Supprime la 1ere sous-chaine 'abc'
ABC123ABCabc
echo ${stringZ//abc}          # Supprime toutes les sous-chaine 'abc'
ABC123ABC

```

http://tldp.org/LDP/abs/html/string-manipulation.html

### Majuscule / Capitalize:

```bash
string=bonjour

# 1ere lettre en majuscule (Bash 4)
echo ${string^}
Bonjour

# Met en majuscule toute la chaine (Bash 4)

echo ${string^^}
BONJOUR

echo $string | tr '[:lower:]' '[:upper:]'
echo $string | awk '{print toupper($0)}'
echo $string | tr '[a-z]' '[A-Z]'
BONJOUR


string=HelLo

# 1ere lettre en minuscule (Bash 4)
echo ${string,}
helLo

# Met en minuscule toute la chaine
echo ${string,,}
hello

echo $string | awk '{print tolower($0)}'
echo $string | tr '[:upper:]' '[:lower:]'


```

```bash
phrase="bonjour tout le monde"

# Capitalise tous les mots (1)
B=( $phrase )
caps="${B[@]^}"
echo "$caps"
Bonjour Tout Le Monde

# Capitalise tous les mots (2)
for i in $phrase; do B=`echo "${i:0:1}" | tr a-z A-Z`${i:1}; caps+="$B "; done
echo "$caps"
Bonjour Tout Le Monde

# Capitalise tous les mots (3)
caps=$(echo "${phrase}" | awk '{for(i=1;i<=NF;i++)sub(/./,toupper(substr($i,1,1)),$i)}1')
echo "$caps"
Bonjour Tout Le Monde

```



### Parcourrir une variable multi-ligne:

```bash
dependencies=$(echo "CairoSVG,setuptools" | xargs pipdeptree -r -p )
```

```bash
while IFS= read -r line; do
				
		echo "${line}"
					
done <<< "$dependencies"

# IFS= requis pour afficher les espaces en début de ligne

```

### Variable multi-line -> une ligne avec espaces

```bash
$ c=$(cat ~/.cryptos.yaml | yq '.lots[] | select(.quantity != 0) | .symbol')
BTC
ETH

$ c=$(cat ~/.cryptos.yaml | yq '.lots[] | select(.quantity != 0) | .symbol' | tr '\n' ' ')
BTC ETH

$ c=$(cat ~/.cryptos.yaml | yq '.lots[] | select(.quantity != 0) | .symbol' | tr -d '\n')
BTCETH
```



#### Regex:

[[ STRING =~ REGEX ]]

[Regular Expression Matching](rematch.md)

Chaine commençant par:

```bash
# String est une url ?

if [[ $string =~ ^http ]]; then 
```

Chaine se terminant par:

```bash
# String est un fichier .mp3 ?

if [[ $string =~ .mp3$ ]]; then 
```

Adresse IP:

```bash
if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then 
```

Email:

```bash
if [[ "$email" =~ "^[A-Za-z0-9._%+-]+<b>@</b>[A-Za-z0-9.-]+<b>\.</b>[A-Za-z]{2,4}$" ]] 
```



Rechercher une sous-chaine

```bash
name=testjohntext

if [[ "$name" == *john* ]]; then
   echo "The string \"john\" was found in the variable \$name"
fi

[[ "$name" == *john* ]] && echo "The string \"john\" was found in the variable \$name"
The string "john" was found in the variable $name

```

Regex

```bash
mytest="The quick brown fox"

[[ "$mytest" =~ The..uick.b..w* ]] && echo "We found a match"
We found a match

```



### IFS (internet field separator)

```bash
$ old_IFS=$IFS

$ IFS=-

$ read day month year
25-12-2013

$ echo $day
25

$ echo $month
12

$ echo $year
2013
$ IFS=old_IFS
```



```bash
$ reg=("Bourgogne" "Burgundy" "Bourgogne Franche-Comté" "Côte d'or" "cotedor")

$ echo "$reg"
Bourgogne Burgundy Bourgogne Franche-Comté Côte d'or cotedor


$ t=${reg[@]}

$ echo "$t"
Bourgogne Burgundy Bourgogne Franche-Comté Côte d'or cotedor


# ${A[@]} is essentially the same as ${A[*]}, differing only when they are in double quotes. When double quoted, * uses the first character of IFS as the separator.

$ t=${reg[*]}

$ echo "$t"
Bourgogne Burgundy Bourgogne Franche-Comté Côte d'or cotedor


$ t=${reg[@]}

$ S=${t// /}

$ echo "$S"
BourgogneBurgundyBourgogneFranche-ComtéCôted'orcotedor

```



### URL

```bash
$ myurl='http://www.example.com/long/path/to/example/file.ext'

$ echo ${myurl##*/}
file.ext

awk -F / '{print $NF}'

$ echo ${myurl#*//}
www.example.com/long/path/to/example/file.ext

$ echo ${myurl%/*}
http://www.example.com/long/path/to/example

$ echo "$myurl" | grep -Eo '^http[s]?://[^/]+'
http://www.example.com
```



| **Parameter Expansion**     | **Description**                                              |
| --------------------------- | ------------------------------------------------------------ |
| ${variable:-value}          | Si la variable est <u>unset</u> ou <u>undefined</u>, développez la **valeur**. |
| ${variable:=value}          | Si la variable est <u>unset</u> ou <u>undefined</u>, définissez la **valeur** sur la variable. |
| ${variable:+value}          | Si la variable est <u>set</u> ou <u>defined</u>, développez la **valeur**. |
| ${variable:?value}          | Si la variable est <u>unset</u> ou <u>undefined</u>, le développement de mot (ou un message à cet effet si mot n'est pas présent) est <u>écrit dans l'erreur standard</u> et le shell, s'il n'est pas interactif, se termine. Sinon, la valeur du paramètre est remplacée. |
| ${#variable}                | <u>Longueur</u> de la variable.<br />Pour un tableau, le nombre d'éléments |
| ${variable/#pattern/string} | Si le modèle existe au début de la variable, remplacez l'occurrence par une chaîne. |
| ${variable/%pattern/string} | Si le modèle existe à la fin de la variable, remplacez l'occurrence par une chaîne. |



|                             | **Rechercher / remplacer**                                   |
| --------------------------- | ------------------------------------------------------------ |
| ${variable/pattern/string}  | Remplacez la partie de la variable par une chaîne où le modèle correspond pour la première fois. |
| ${variable//pattern/string} | Remplacez toutes les occurrences de la variable par une chaîne où tous les modèles correspondent. |
|                             |                                                              |
|                             |                                                              |



|                             | **Sous-chaines**                                             |
| --------------------------- | ------------------------------------------------------------ |
| ${variable:start:length}    | La sous-chaîne récupérera de la position de <u>départ</u> à la position de <u>longueur</u> de la variable. |
| ${variable:(-start):length} | idem en partant de la fin                                    |
| ${variable:start}           | La sous-chaîne récupérera de la position de <u>départ</u> à la partie restante de la variable. |
| ${variable:(-start)}        | idem en partant de la fin                                    |



|                      | **Suppression de sous-chaines**                              |
| -------------------- | ------------------------------------------------------------ |
| ${variable#pattern}  | Supprimez la correspondance la plus courte depuis le début de la variable où le modèle correspond.<br /><br />Remove the shortest match from the beginning of the variable where the pattern matches. |
| ${variable##pattern} | Supprimez la correspondance la plus longue depuis le début de la variable où le modèle correspond. |
| ${variable%pattern}  | Supprimez la correspondance la plus courte à partir de la fin de la variable où le modèle correspond. |
| ${variable%%pattern} | Supprimez la correspondance la plus longue à partir de la fin de la variable où le modèle correspond. |



|               | **Changement de case**          |
| ------------- | ------------------------------- |
| ${variable^}  | Met la 1ere lettre en majuscule |
| ${variable^^} | Met tout le mot en majuscule    |
| ${variable,}  | Met la 1ere lettre en minuscule |
| ${variable,,} | Met tout le mot en minuscule    |
| ${variable~}  | Inverse la 1ere lettre          |
| ${variable~~} | Inverse tout le mot             |



#### **${variable:-value}**: 

```bash
# si la variable est unset ou undefined, développez la valeur:

# 1. myvar n'est pas définie
$ echo "${myvar:-bash}"
bash

$ echo $myvar


# 2. myvar est définie
$ myvar=3
$ echo "${myvar:-bash}"
3

$ echo $myvar
3
```



#### **${variable:=value}**

```bash
# Si la variable est unset ou undefined, définissez la valeur sur la variable:

# 1. myvar n'est pas définie
$ echo "${myvar:=bash}"
bash

$ echo $myvar
bash

# 2. myvar est définie
$ myvar=zsh
$ echo "${myvar:=bash}"
zsh

$ echo $myvar
zsh
```



#### **${variable:+value}**

```bash
# Si la variable est set ou defined, développez la valeur:

# 1. myvar n'est pas définie
$ echo "${myvar:+python}"


# 2. myvar est définie
$ myvar=zsh
$ echo "${myvar:+python}"
python

$ echo $myvar
zsh
```



#### **${variable:?value}**

```bash

# 1. myvar n'est pas définie
$ echo "${myvar:?bash}"
bash: myvar: bash

# 2. myvar est définie
$ myvar=zsh
$ echo "${myvar:?bash}"
zsh

$ echo $myvarzsh
zsh
```



#### **${variable:start:length}**

```bash
# La sous-chaîne récupérera de la position de départ à la position de longueur de la variable.

$ myvar="La sous-chaîne récupérera de la position de départ à la position de longueur de la variable."

$ echo "${myvar:15:35}"
récupérera de la position de départ

$ echo "${myvar:(-15):35}"			# Séparer l'offset des : avec les parenthèses ()
de la variable.
```



#### **${variable:start}**

```bash
# La sous-chaîne récupérera de la position de départ à la partie restante de la variable.

$ myvar="La sous-chaîne récupérera de la position de départ à la partie restante de la variable."

$ echo "${myvar:15}"
récupérera de la position de départ à la partie restante de la variable.

$ echo "${myvar:(-15)}"				# Séparer l'offset des : avec les parenthèses ()
de la variable.
```



#### **${\#variable}** **${\#array}**

```bash
# Longueur de la variable.

$ myvar="Longueur de la variable."
$ echo "${#myvar}"
24

$ array=("name" "word")
$ echo "${#array}"
```



#### **${variable/pattern/string}**

```bash
# Remplacez la partie de la variable par une chaîne où le modèle correspond pour la première fois.

$ myvar="Remplacez la partie de la variable par une chaîne où le modèle correspond pour la première fois."
$ echo "${myvar/la/the}"
Rempthecez la partie de la variable par une chaîne où le modèle correspond pour la première fois.
```



#### **${variable//pattern/string}**

```bash
# Remplacez toutes les occurrences de la variable par une chaîne où tous les modèles correspondent.

$ myvar="Remplacez toutes les occurrences de la variable par une chaîne où tous les modèles correspondent."
$ echo "${myvar//les/the}"
Remplacez toutes the occurrences de la variable par une chaîne où tous the modèthe correspondent.
```



#### **${variable/#pattern/string}**

```bash
# Si le modèle existe au début de la variable, remplacez l'occurrence par une chaîne.

$ myvar="Si le modèle existe au début de la variable, remplacez l'occurrence par une chaîne"
$ echo "${myvar/#les/If}"
Si le modèle existe au début de la variable, remplacez l'occurrence par une chaîne

$ echo "${myvar/#Si/If}"
If le modèle existe au début de la variable, remplacez l'occurrence par une chaîne
```



#### **${variable/%pattern/string}**

```bash
# Si le modèle existe à la fin de la variable, remplacez l'occurrence par une chaîne.

$ myvar="Si le modèle existe à la fin de la variable, remplacez l'occurrence par une chaîne."

$ echo "${myvar/%chaine./laisse.}"	# i
Si le modèle existe à la fin de la variable, remplacez l'occurrence par une chaîne.

$ echo "${myvar/%chaîne/laisse}"		# î
Si le modèle existe à la fin de la variable, remplacez l'occurrence par une laisse
```



#### **${variable#pattern}**

```bash
# Supprimez la correspondance la plus courte depuis le début de la variable où le modèle correspond.
# Remove the shortest match from the beginning of the variable where the pattern matches.

$ myvar="Supprimez la correspondance la plus courte depuis le début de la variable où le modèle correspond."

$ echo "${myvar#*la}"				# du début au 1er la
 correspondance la plus courte depuis le début de la variable où le modèle correspond.
```



#### **${variable##pattern}**

```bash
# Supprimez la correspondance la plus longue depuis le début de la variable où le modèle correspond.

$ myvar="Supprimez la correspondance la plus longue depuis le début de la variable où le modèle correspond."

$ echo "${myvar##*la}"		# du début au dernier la
 variable où le modèle correspond.
```



#### **${variable%pattern}**

```bash
# Supprimez la correspondance la plus courte à partir de la fin de la variable où le modèle correspond.

$ myvar="Supprimez la correspondance la plus courte à partir de la fin de la variable où le modèle correspond."

$ echo "${myvar%la*}"
Supprimez la correspondance la plus courte à partir de la fin de
```



#### **${variable%%pattern}**

```bash
# Supprimez la correspondance la plus longue à partir de la fin de la variable où le modèle correspond.

$ myvar="Supprimez la correspondance la plus longue à partir de la fin de la variable où le modèle correspond."

$ echo "${myvar%%la*}"
Supprimez
```



#### **Exemples avec les chemins / fichiers:**

```bash
$ PATHNAME=/Users/bruno/Pictures/Export/2022/Juillet/2022-07-01_Chevrette_3462.jpg

# Obtenir le répertoire:
$ echo ${PATHNAME%/*}
/Users/bruno/Pictures/Export/2022/Juillet

# Obtenir le nom de fichier:
$ echo ${PATHNAME##*/}
2022-07-01_Chevrette_3462.jpg


$ FILENAME=2022-07-01_Chevrette_3462.jpg

# Obtenir le nom de fichier sans extension:
$ echo ${FILENAME%.*}
2022-07-01_Chevrette_3462

# Obtenir l'extension:
$ echo ${FILENAME##*.}
jpg
```





https://wiki.bash-hackers.org/syntax/pe#substring_removal



