Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Les deux révisions précédentesRévision précédente
Prochaine révision
Révision précédente
informatique:outils:bash [2024/10/30 10:35] – [Barre de progression] bn8informatique:outils:bash [2025/08/21 12:47] (Version actuelle) – [Barre de progression] bn8
Ligne 7: Ligne 7:
     * Pour chercher explicitement **à la fin** du contenu de la variable : ''${parameter/%search_pattern/replacement}''     * Pour chercher explicitement **à la fin** du contenu de la variable : ''${parameter/%search_pattern/replacement}''
     * Pour remplacer **toutes les occurences** : ''%%${parameter//search_pattern/replacement}%%''     * Pour remplacer **toutes les occurences** : ''%%${parameter//search_pattern/replacement}%%''
-  * Mise en **majuscule** : ''${variable^}'' => mise en majuscule du première caractère du contenu de la variable ''variable''+  * Mise en **majuscule** (upper case) : ''${variable^}'' => mise en majuscule du première caractère du contenu de la variable ''variable''
     * Pour mettre **tout en majuscule** : ''${variable^^}''     * Pour mettre **tout en majuscule** : ''${variable^^}''
-  * Mise en **minuscule** : ''${variable,}'' => mise en minuscule du première caractère du contenu de la variable ''variable''+  * Mise en **minuscule** (lower case) : ''${variable,}'' => mise en minuscule du première caractère du contenu de la variable ''variable''
     * Pour mettre **tout en minuscule** : ''${variable,,}''     * Pour mettre **tout en minuscule** : ''${variable,,}''
  
Ligne 25: Ligne 25:
     * avec un retour à la ligne : ''%%mapfile -t myarray <<< "$ALL"%%''     * avec un retour à la ligne : ''%%mapfile -t myarray <<< "$ALL"%%''
     * avec un espace (ou autre caractère unique et "simple) : ''%%IFS=" " read -ra myarray <<< "$ALL"%%''     * avec un espace (ou autre caractère unique et "simple) : ''%%IFS=" " read -ra myarray <<< "$ALL"%%''
 +    * ajouter des valeurs à un tableau existant : ''%%mapfile -t -O "${#myarray[@)}" myarray <<< "$ALL"%%''
 +    * ajouter depuis un fichier : ''%%mapfile -t myarray < /path/to/file%%''
 +    * ajouter depuis la sortie d'une commande : ''%%mapfile -t myarray < <( grep -vE '^#' /path/to/file | grep -vE '^\s*$' )%%''
     * Note : voir la fonction ''explode'' pour une version générique     * Note : voir la fonction ''explode'' pour une version générique
  
 ==== Fonctions utiles ==== ==== Fonctions utiles ====
- 
  
 === in_array === === in_array ===
Ligne 183: Ligne 185:
 # Output: # Output:
 # declare -a myarray=([0]="1" [1]="2" [2]="3") # declare -a myarray=([0]="1" [1]="2" [2]="3")
 +</code>
 +
 +=== check_regex ===
 +
 +<code bash>
 +function check_regex() {
 +  [[ $(grep -Ec "$2" <<< "$1") -eq 1 ]] && return 0
 +  return 1
 +
 +</code>
 +
 +=== check_int ===
 +
 +**Pré-requis :** [[#check_regex]]
 +
 +<code bash>
 +function check_int() {
 +    check_regex "$1" '^-?[0-9]+$' || return 1
 +    [[ -n "$2" ]] && [[ $1 -lt $2 ]] && return 1
 +    [[ -n "$3" ]] && [[ $1 -gt $3 ]] && return 1
 +    return 0
 +}
 </code> </code>
  
Ligne 196: Ligne 220:
     [[ $d -gt 0 ]] && printf '%d days and ' $d     [[ $d -gt 0 ]] && printf '%d days and ' $d
     printf '%02d:%02d:%02d' $h $m $s     printf '%02d:%02d:%02d' $h $m $s
 +}
 +</code>
 +
 +=== format_size ===
 +
 +**Pré-requis :** [[#check_int]]
 +
 +<code bash>
 +declare -ra _FORMAT_SIZE_UNITS=( tb gb mb kb b )
 +declare -rA _FORMAT_SIZE_UNITS_FACTOR=(
 +    ["tb"]=1099511627776 ["gb"]=1073741824 ["mb"]=1048576 ["kb"]=1024 ["b"]=1 )
 +function format_size() {
 +    local size="" unit=kb allow_zero=0 negative=0 opt
 +    for opt in "$@"; do
 +        opt="${opt,,}"
 +        if [[ ${#opt} -gt 2 ]] && \
 +            [[ "${_FORMAT_SIZE_UNITS_FACTOR[${opt:2}]:-null}" != "null" ]]; then
 +            unit=${opt:2}
 +        elif [[ ${#opt} -gt 1 ]] && \
 +            [[ "${_FORMAT_SIZE_UNITS_FACTOR[${opt:1}]:-null}" != "null" ]]; then
 +            unit=${opt:1}
 +        elif [[ "$opt" == "--allow-zero" ]] || [[ "$opt" == "-z" ]]; then
 +            allow_zero=1
 +        elif [[ -z "$size" ]]; then
 +            size=$opt
 +            [[ "$size" == "null" ]] && echo -n null && return
 +            check_int "$size" || { echo -n "format_size: invalid value '$size'"; return 1; }
 +        else
 +            echo -n "format_size: invalid parameter '$opt'"
 +            return 1
 +        fi
 +    done
 +    if [[ $size -eq 0 ]]; then
 +        [[ $allow_zero -eq 0 ]] && return
 +        echo -n "0${_FORMAT_SIZE_UNITS[${#_FORMAT_SIZE_UNITS[@]} - 1]}"
 +    elif [[ $size -lt 0 ]]; then
 +        (( size=size*-1 ))
 +        negative=1
 +    fi
 +
 +    (( size=size*${_FORMAT_SIZE_UNITS_FACTOR[$unit]} ))
 +    for unit in "${_FORMAT_SIZE_UNITS[@]}"; do
 +        [[ $size -lt ${_FORMAT_SIZE_UNITS_FACTOR[$unit]} ]] && continue
 +        if [[ $size -eq ${_FORMAT_SIZE_UNITS_FACTOR[$unit]} ]]; then
 +            size=1
 +        else
 +            size=$( echo "scale=1; $size/${_FORMAT_SIZE_UNITS_FACTOR[$unit]}"|bc|sed 's/\.0$//' )
 +        fi
 +        [[ $negative -eq 1 ]] && size=$( echo "$size*-1"|bc )
 +        echo -n "${size}${unit^^}"
 +        return
 +    done
 } }
 </code> </code>
Ligne 224: Ligne 300:
 <code bash>declare -p variableName</code> <code bash>declare -p variableName</code>
  
 +=== sprint ===
 +
 +**Pré-requis :** [[#implode]]
 +
 +<code bash>
 +#
 +# Styled text printing helper
 +#
 +declare -rA COLORS=(
 +    [black]=30 [red]=31 [green]=32 [brown]=33 [blue]=34 [purple]=35 [cyan]=36 [light_grey]=37
 +    [default]=39 [dark_grey]=90 [light_red]=91 [light_green]=92 [yellow]=93 [light_blue]=94
 +    [light_purple]=95 [light_cyan]=96 [white]=97
 +)
 +declare -rA BACKGROUND_COLORS=(
 +    [black]=40 [red]=41 [green]=42 [brown]=43 [blue]=44 [purple]=45 [cyan]=46 [ligth_grey]=47
 +    [default]=49 [dark_grey]=100 [light_red]=101 [light_green]=102 [yellow]=103 [light_blue]=104
 +    [light_purple]=105 [light_cyan]=106 [white]=107
 +)
 +declare -rA TEXT_STYLES=(
 +    [normal]=0 [bold]=1 [dim]=2 [italic]=3 [underline]=4 [blink]=5 [inverted_colors]=7 [hidden]=8
 +    [strikethrough]=9
 +)
 +declare -rA RESET_STYLES=(
 +    [all]=0 [bold]=21 [dim]=22 [underline]=24 [blink]=25 [inverted_colors]=27 [hidden]=28
 +)
 +
 +function sprint() {
 +    local idx=1 opt value no_newline=0 output=""
 +    local -a styles=() text=()
 +
 +    __sprint() {
 +        [[ -n "$output" ]] && output+=" "
 +        [[ "${#styles}" -gt 0 ]] && \
 +            output+="\e[$(implode ';' "${styles[@]}")m" && \
 +            styles=()
 +        output+="${text[*]}"
 +        text=()
 +    }
 +    while [[ $idx -le $# ]]; do
 +        opt=${!idx}
 +        case $opt in
 +            -c|--color)
 +                [[ "${#text}" -gt 0 ]] && __sprint
 +                ((idx++))
 +                value="${!idx,,}"
 +                if [[ "${COLORS[$value]:-null}" == "null" ]]; then
 +                    echo -n "sprint: invalid color '${!idx}'"
 +                    return 1
 +                fi
 +                styles+=( "${COLORS[$value]}" )
 +                ;;
 +            -b|--bg)
 +                [[ "${#text}" -gt 0 ]] && __sprint
 +                ((idx++))
 +                value="${!idx,,}"
 +                if [[ "${BACKGROUND_COLORS[$value]:-null}" == "null" ]]; then
 +                    echo -n "sprint: invalid background color '${!idx}'"
 +                    return 1
 +                fi
 +                styles+=( "${BACKGROUND_COLORS[$value]}" )
 +                ;;
 +            -s|--style)
 +                [[ "${#text}" -gt 0 ]] && __sprint
 +                ((idx++))
 +                value="${!idx,,}"
 +                if [[ "${TEXT_STYLES[$value]:-null}" == "null" ]]; then
 +                    echo -n "sprint: invalid text style '${!idx}'"
 +                    return 1
 +                fi
 +                styles+=( "${TEXT_STYLES[$value]}" )
 +                ;;
 +            -r|--reset)
 +                [[ "${#text}" -gt 0 ]] && __sprint
 +                ((idx++))
 +                value="${!idx,,}"
 +                if [[ "${RESET_STYLES[$value]:-null}" == "null" ]]; then
 +                    echo -n "sprint: invalid reset option '${!idx}'"
 +                    return 1
 +                fi
 +                output+="\e[${RESET_STYLES[$value]}m"
 +                ;;
 +            -n)
 +                no_newline=1
 +                ;;
 +            -h|--help)
 +                echo "usage: sprint [-n] [-c color] [-b color] [-s style] [words] [-r what] [...]"
 +                echo "  -c / --color [color]   Colored text. Available colors:"
 +                implode ", " "${!COLORS[@]}" | \
 +                    fold -w 53 -s | sed "s/^/                         /g"
 +                echo
 +                echo "  -b / --bg [color]      Text background color. Available colors:"
 +                implode ", " "${!BACKGROUND_COLORS[@]}" | \
 +                    fold -w 53 -s | sed "s/^/                         /g"
 +                echo
 +                echo "  -s / --style [style]   Text style. Available styles:"
 +                implode ", " "${!TEXT_STYLES[@]}" | \
 +                    fold -w 53 -s | sed "s/^/                         /g"
 +                echo
 +                echo "  -r / --reset [what]    Reset some previously specified styles. Available reset clauses:"
 +                implode ", " "${!RESET_STYLES[@]}" | \
 +                    fold -w 53 -s | sed "s/^/                         /g"
 +                echo
 +                echo "  -n                     Do not add new line"
 +                echo "  [words]                Words that compose the text"
 +                ;;
 +            *)
 +                text+=( "$opt" )
 +        esac
 +        ((idx++))
 +    done
 +    __sprint
 +    output+="\e[${RESET_STYLES[all]}m"
 +    if [[ "$no_newline" -eq 1 ]]; then
 +        echo -en "$output"
 +    else
 +        echo -e "$output"
 +    fi
 +}
 +</code>
 +
 +**Exemple :**
 +<code bash>
 +sprint -c red '[' -s blink ERROR -r blink ']' -r all Really bad error occurred -s dim -s italic '(see log for details)'
 +</code>
 +
 +Résultat : 
 +
 +{{:informatique:outils:sprint.svg?500|}}
 ===== Gestion des paramètres ===== ===== Gestion des paramètres =====
  
Ligne 287: Ligne 491:
 <code bash> <code bash>
 declare -A PBARS declare -A PBARS
-declare PBID 
  
 # Create a progress bar # Create a progress bar
Ligne 294: Ligne 497:
 # - total count (default: 100) # - total count (default: 100)
 # - bar size (default: use all the width of the terminal with a minimum of 5 caracters) # - 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)+# - the name of the variable use to store the progress bar ID (default: PBAR)
 function pbar_create() { function pbar_create() {
-    # Define the name of the variable that will store the progress bar ID +    local id=${4:-PBAR}
-    local pbar_id_var=${4:-}; [[ -z "$pbar_id_var" ]] && pbar_id_var=PBID +
-    local -n id="$pbar_id_var" +
-    # Generate the progress bar ID +
-    id="$( tr -dc A-Za-z0-9 </dev/urandom | head -c 3 )"+
     # Initialize progress bar information     # Initialize progress bar information
     PBARS["${id}_START_TIME"]="$( date +%s )"     PBARS["${id}_START_TIME"]="$( date +%s )"
Ligne 315: Ligne 514:
 # Finish a progress bar # Finish a progress bar
 # Arguments: # Arguments:
-# - the ID of the progress bar (default: $PBID)+# - the ID of the progress bar (default: PBAR)
 function pbar_finish() { function pbar_finish() {
-    local id=${1:-}; [[ -z "$id" ]] && id=$PBID+    local id=${1:-PBAR}
  
     # Force a last update of the progess bar     # Force a last update of the progess bar
Ligne 335: Ligne 534:
 # Draw the progress bar # Draw the progress bar
 # Arguments: # Arguments:
-# - the ID of the progress bar (default: $PBID)+# - the ID of the progress bar (default: PBAR)
 # - extra message to display in the progress bar (before the ETA, optional) # - 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 # - all extra arguments will be use to compute the extra message using printf
 function pbar_draw() { function pbar_draw() {
-    local id=${1:-}; [[ -z "$id" ]] && id=$PBID+    local id=${1:-PBAR}
  
     # Compute extra message     # Compute extra message
Ligne 416: Ligne 615:
 # Increment the progress bar # Increment the progress bar
 # Arguments: # Arguments:
-# - the ID of the progress bar (default: $PBID)+# - the step (default: 1) 
 +# - the ID of the progress bar (default: PBAR)
 # - extra message to display in the progress bar (before the ETA, optional) # - 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 # - all extra arguments will be use to compute the extra message using printf
 function pbar_increment() { function pbar_increment() {
-    local id=${1:-}; [[ -z "$id" ]] && id=$PBID+    local step=${1:-1} id=${2:-PBAR}
     # Increment the progress bar state     # Increment the progress bar state
-    ((PBARS[${id}_CURRENT]++))+    ((PBARS[${id}_CURRENT]+=step))
     # Draw the progress bar     # Draw the progress bar
-    pbar_draw "$@"+    pbar_draw "${@:2}"
 } }
 </code> </code>
Ligne 442: Ligne 642:
 pbar_create "Test" 20 pbar_create "Test" 20
 for i in $( seq 1 20 ); do for i in $( seq 1 20 ); do
-    pbar_increment "" "%d iteration(s) - %d found(s)" $i $(( i/2 ))+    pbar_increment "" "" "%d iteration(s) - %d found(s)" $i $(( i/2 ))
     sleep 0.1     sleep 0.1
 done done
-pbar_finish "" "%d iteration(s) - %d found(s)" $i $(( i/2 ))+pbar_finish "" "" "%d iteration(s) - %d found(s)" $i $(( i/2 ))
 </code> </code>
  
 <note warning>La fonction [[#format_duration]] est nécessaire.</note> <note warning>La fonction [[#format_duration]] est nécessaire.</note>