Différences
Ci-dessous, les différences entre deux révisions de la page.
Les deux révisions précédentes Révision précédente Prochaine révision | Révision précédente | ||
informatique:outils:bash [2024/03/25 13:07] – [Fonctions utiles] bn8 | informatique:outils:bash [2024/10/30 14:07] (Version actuelle) – [Array] bn8 | ||
---|---|---|---|
Ligne 1: | Ligne 1: | ||
====== Bash ====== | ====== Bash ====== | ||
+ | |||
+ | ===== Substitution dans les variables ===== | ||
+ | |||
+ | * Chercher/ | ||
+ | * Pour chercher explicitement **au début** du contenu de la variable : '' | ||
+ | * Pour chercher explicitement **à la fin** du contenu de la variable : '' | ||
+ | * Pour remplacer **toutes les occurences** : '' | ||
+ | * Mise en **majuscule** (upper case) : '' | ||
+ | * Pour mettre **tout en majuscule** : '' | ||
+ | * Mise en **minuscule** (lower case) : '' | ||
+ | * Pour mettre **tout en minuscule** : '' | ||
===== Array ===== | ===== Array ===== | ||
- | * déclaration : '' | + | * déclaration : '' |
+ | * déclaration d'un tableau associatif : '' | ||
+ | * déclaration d'un tableau en lecture seule : '' | ||
* ajouter un élément : '' | * ajouter un élément : '' | ||
- | * lister tous les éléments : '' | + | |
- | * récupérer le nombre d'élement | + | |
+ | * lister toutes les clés d'un tableau associatif : '' | ||
+ | * récupérer le nombre d'élements d'un tableau | ||
+ | * construire un tableau à partir d'une chaîne de caractères : Cela dépend du séparateur utilisé : | ||
+ | * avec un retour à la ligne : '' | ||
+ | * avec un espace (ou autre caractère unique et " | ||
+ | * ajouter des valeurs à un tableau existant : '' | ||
+ | * ajouter depuis un fichier : '' | ||
+ | * ajouter depuis la sortie d'une commande : '' | ||
+ | * Note : voir la fonction '' | ||
==== Fonctions utiles ==== | ==== Fonctions utiles ==== | ||
Ligne 45: | Ligne 67: | ||
is_empty $array && echo empty | is_empty $array && echo empty | ||
! is_empty $array && echo not empty | ! is_empty $array && echo not empty | ||
+ | </ | ||
+ | |||
+ | === array_filter === | ||
+ | |||
+ | <code bash> | ||
+ | function array_filter() { | ||
+ | local values=() x=0 v | ||
+ | for v in " | ||
+ | if [[ " | ||
+ | x=1 | ||
+ | elif [[ $x -eq 0 ]]; then | ||
+ | values+=( " | ||
+ | else | ||
+ | mapfile -t values < <( printf ' | ||
+ | fi | ||
+ | done | ||
+ | printf ' | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | **Utilisation :** | ||
+ | <code bash> | ||
+ | a=(a b c d e) | ||
+ | array_filter ${a[@]} -- c e | ||
+ | # Output: | ||
+ | # a | ||
+ | # b | ||
+ | # d | ||
+ | </ | ||
+ | |||
+ | === array_intersect === | ||
+ | |||
+ | <code bash> | ||
+ | function array_intersect() { | ||
+ | local result_var=$1 | ||
+ | declare -ga " | ||
+ | shift | ||
+ | local array1=() | ||
+ | local array2=() | ||
+ | local switch_to_array2=0 | ||
+ | |||
+ | for v in " | ||
+ | if [ " | ||
+ | switch_to_array2=1 | ||
+ | elif [ $switch_to_array2 -eq 0 ]; then | ||
+ | array2+=( " | ||
+ | else | ||
+ | array1+=( " | ||
+ | fi | ||
+ | done | ||
+ | |||
+ | for i in " | ||
+ | for j in " | ||
+ | if [[ $i == $j ]]; then | ||
+ | declare -ga " | ||
+ | break | ||
+ | fi | ||
+ | done | ||
+ | done | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | **Utilisation :** | ||
+ | <code bash> | ||
+ | a=(a b c d e) | ||
+ | b=(c d) | ||
+ | array_intersect c " | ||
+ | echo " | ||
+ | # Result: | ||
+ | c d | ||
</ | </ | ||
Ligne 68: | Ligne 160: | ||
# - 2 | # - 2 | ||
# - 3 | # - 3 | ||
+ | </ | ||
+ | |||
+ | === explode === | ||
+ | |||
+ | <code bash> | ||
+ | function explode() { | ||
+ | local output_var=$1 seperator=$2 | ||
+ | declare -ga " | ||
+ | mapfile -t " | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | **Utilisation :** | ||
+ | <code bash> | ||
+ | explode myarray " " "1 2 3" "4 5" | ||
+ | declare -p myarray | ||
+ | # Output: | ||
+ | # declare -a myarray=([0]=" | ||
+ | |||
+ | explode myarray " | ||
+ | 1 | ||
+ | 2 | ||
+ | 3" | ||
+ | declare -p myarray | ||
+ | # Output: | ||
+ | # declare -a myarray=([0]=" | ||
</ | </ | ||
Ligne 74: | Ligne 192: | ||
<code bash> | <code bash> | ||
function format_duration { | function format_duration { | ||
- | | + | |
- | local D=$((T/ | + | local d=$((t/ |
- | local H=$((T/ | + | local h=$((t/ |
- | local M=$((T/60%60)) | + | local m=$((t/60%60)) |
- | local S=$((T%60)) | + | local s=$((t%60)) |
- | | + | |
- | printf ' | + | printf ' |
} | } | ||
</ | </ | ||
Ligne 173: | Ligne 291: | ||
declare -A PBARS | declare -A PBARS | ||
declare PBID | declare PBID | ||
+ | |||
+ | # Create a progress bar | ||
+ | # Arguments: | ||
+ | # - the progress bar title (default: Progress) | ||
+ | # - total count (default: 100) | ||
+ | # - bar size (default: use all the width of the terminal with a minimum of 5 caracters) | ||
+ | # - the name of the variable use to store the progress bar ID (default: PBID) | ||
function pbar_create() { | function pbar_create() { | ||
- | | + | # Define the name of the variable that will store the progress bar ID |
- | | + | local pbar_id_var=${4: |
- | ID=$( tr -dc A-Za-z0-9 </ | + | |
- | PBARS[" | + | # Generate the progress bar ID |
- | PBARS[" | + | id="$( tr -dc A-Za-z0-9 </ |
- | PBARS[" | + | # Initialize progress bar information |
- | PBARS[" | + | |
- | pbar_draw $ID | + | [ -n " |
+ | [ -n " | ||
+ | [ -n " | ||
+ | PBARS[" | ||
+ | | ||
+ | PBARS[" | ||
+ | # Draw the progress bar for a first time | ||
+ | | ||
} | } | ||
+ | # Finish a progress bar | ||
+ | # Arguments: | ||
+ | # - the ID of the progress bar (default: $PBID) | ||
function pbar_finish() { | function pbar_finish() { | ||
- | | + | local id=${1:-}; [[ -z "$id" |
- | unset ' | + | |
- | unset ' | + | # Force a last update of the progess bar |
- | unset ' | + | PBARS[" |
- | unset ' | + | pbar_draw " |
- | echo | + | |
+ | # Unset progress bar info | ||
+ | unset ' | ||
+ | unset ' | ||
+ | unset ' | ||
+ | unset ' | ||
+ | unset ' | ||
+ | unset ' | ||
+ | | ||
} | } | ||
+ | # Draw the progress bar | ||
+ | # Arguments: | ||
+ | # - the ID of the progress bar (default: $PBID) | ||
+ | # - extra message to display in the progress bar (before the ETA, optional) | ||
+ | # - all extra arguments will be use to compute the extra message using printf | ||
function pbar_draw() { | function pbar_draw() { | ||
- | | + | local id=${1:-}; [[ -z " |
- | let PERC=${PBARS[${ID}_CURRENT]}*100/ | + | |
- | let DURATION=$(date +%s)-${PBARS[${ID}_START_TIME]} | + | # Compute extra message |
- | if [ ${PBARS[${ID}_CURRENT]} -gt 0 ] | + | local extra=${2: |
- | | + | # shellcheck disable=SC2059 |
- | let TOTAL_DURATION=DURATION*${PBARS[${ID}_TOTAL]}/ | + | [[ -n "$extra" |
+ | |||
+ | # Only update progress bar one time by second | ||
+ | local now; now=$(date +%s) | ||
+ | [[ " | ||
+ | |||
+ | # Compute progress percentage | ||
+ | local perc | ||
+ | (( perc=${PBARS[${id}_CURRENT]}*100/ | ||
+ | |||
+ | # Compute line without the progress bar | ||
+ | local line line_items line_pad size line_length term_height term_width bar_done bar_pad | ||
+ | line_items=( | ||
+ | "${PBARS[${id}_TITLE]}" | ||
+ | " | ||
+ | " | ||
+ | ) | ||
+ | [ -n " | ||
+ | |||
+ | # Add ETA (or total duration if finish) | ||
+ | if [[ "${PBARS[${id}_END_TIME]}" | ||
+ | # Compute duration, total duration, ETA & speed | ||
+ | local duration total_duration speed eta | ||
+ | (( duration=now-${PBARS[${id}_START_TIME]} | ||
+ | if [[ "${PBARS[${id}_CURRENT]}" | ||
+ | (( total_duration=duration*${PBARS[${id}_TOTAL]}/ | ||
+ | speed=$( bc <<< | ||
else | else | ||
- | TOTAL_DURATION=0 | + | total_duration=0 |
+ | speed="?" | ||
fi | fi | ||
- | | + | |
- | let DONE=$PERC*4/ | + | |
- | let LEFT=40-$DONE | + | |
- | DONE=$(printf " | + | |
- | LEFT=$(printf " | + | |
- | | + | |
- | | + | |
- | "${DONE}" "${LEFT}" | + | "- $( printf "(%s / %s, %s/s)" "$(format_duration $duration)" |
- | ${PBARS[${ID}_CURRENT]} ${PBARS[${ID}_TOTAL]} \ | + | ) |
- | $PERC \ | + | else |
- | "$(format_duration | + | local total_duration |
- | "$(format_duration | + | (( total_duration=${PBARS[${id}_END_TIME]}-${PBARS[${id}_START_TIME]} )) |
- | "$(format_duration | + | line_items+=( |
+ | fi | ||
+ | |||
+ | # Compute progress bar length (if not configured) | ||
+ | # shellcheck disable=SC2034 | ||
+ | read -r term_height term_width < <(stty size) | ||
+ | size=${PBARS[${id}_SIZE]} | ||
+ | if [[ " | ||
+ | line_length=$( wc -c <<< | ||
+ | (( size=term_width-line_length )) | ||
+ | [[ $size -lt 5 ]] && size=5 | ||
+ | fi | ||
+ | |||
+ | # Set progress bar text | ||
+ | (( bar_done=perc*size/ | ||
+ | (( bar_pad=size-bar_done )) | ||
+ | line_items[1]="[$(printf "%${bar_done}s" | ||
+ | |||
+ | # Add line padding (if need) | ||
+ | (( line_pad=term_width-${# | ||
+ | [[ $line_pad -gt 0 ]] && line_items+=( | ||
+ | |||
+ | # Compute & display line (strip the terminal width) | ||
+ | line="${line_items[*]}" | ||
+ | echo -en "\r${line: | ||
+ | |||
+ | # Update last progress bar update time | ||
+ | PBARS[${id}_LAST_UPDATE]=$now | ||
} | } | ||
+ | # Increment the progress bar | ||
+ | # Arguments: | ||
+ | # - the ID of the progress bar (default: $PBID) | ||
+ | # - extra message to display in the progress bar (before the ETA, optional) | ||
+ | # - all extra arguments will be use to compute the extra message using printf | ||
function pbar_increment() { | function pbar_increment() { | ||
- | | + | local id=${1:-}; [[ -z "$id" |
- | ((PBARS[${ID}_CURRENT]++)) | + | # Increment the progress bar state |
- | pbar_draw $ID | + | |
+ | # Draw the progress bar | ||
+ | | ||
} | } | ||
</ | </ | ||
Ligne 229: | Ligne 434: | ||
<code bash> | <code bash> | ||
pbar_create " | pbar_create " | ||
- | for i in $( seq 1 20 ) | + | for i in $( seq 1 20 ); do |
- | do | + | pbar_increment |
- | pbar_increment | + | sleep 0.1 |
- | sleep 0.1 | + | |
done | done | ||
pbar_finish | pbar_finish | ||
+ | </ | ||
+ | |||
+ | **Ajout d'info avant l'ETA :** | ||
+ | <code bash> | ||
+ | pbar_create " | ||
+ | for i in $( seq 1 20 ); do | ||
+ | pbar_increment "" | ||
+ | sleep 0.1 | ||
+ | done | ||
+ | pbar_finish "" | ||
</ | </ | ||
<note warning> | <note warning> |