Question Comment couper des espaces à partir d'une variable Bash?


J'ai un script shell avec ce code:

var=`hg st -R "$path"`
if [ -n "$var" ]; then
    echo $var
fi

Mais le code conditionnel s'exécute toujours, car hg st imprime toujours au moins un caractère de nouvelle ligne.

  • Existe-t-il un moyen simple de supprimer les espaces $var (comme trim() dans PHP)?

ou

  • Existe-t-il un moyen standard de traiter ce problème?

je pourrais utiliser sed ou AWK, mais je voudrais penser qu'il existe une solution plus élégante à ce problème.


653
2017-10-20 23:32


origine


Réponses:


Définissons une variable contenant les espaces de début, de fin et intermédiaires:

FOO=' test test test '
echo -e "FOO='${FOO}'"
# > FOO=' test test test '
echo -e "length(FOO)==${#FOO}"
# > length(FOO)==16

Comment supprimer tous les espaces (désignés par [:space:] dans tr):

FOO=' test test test '
FOO_NO_WHITESPACE="$(echo -e "${FOO}" | tr -d '[:space:]')"
echo -e "FOO_NO_WHITESPACE='${FOO_NO_WHITESPACE}'"
# > FOO_NO_WHITESPACE='testtesttest'
echo -e "length(FOO_NO_WHITESPACE)==${#FOO_NO_WHITESPACE}"
# > length(FOO_NO_WHITESPACE)==12

Comment supprimer les espaces blancs principaux uniquement:

FOO=' test test test '
FOO_NO_LEAD_SPACE="$(echo -e "${FOO}" | sed -e 's/^[[:space:]]*//')"
echo -e "FOO_NO_LEAD_SPACE='${FOO_NO_LEAD_SPACE}'"
# > FOO_NO_LEAD_SPACE='test test test '
echo -e "length(FOO_NO_LEAD_SPACE)==${#FOO_NO_LEAD_SPACE}"
# > length(FOO_NO_LEAD_SPACE)==15

Comment supprimer les espaces de fin uniquement:

FOO=' test test test '
FOO_NO_TRAIL_SPACE="$(echo -e "${FOO}" | sed -e 's/[[:space:]]*$//')"
echo -e "FOO_NO_TRAIL_SPACE='${FOO_NO_TRAIL_SPACE}'"
# > FOO_NO_TRAIL_SPACE=' test test test'
echo -e "length(FOO_NO_TRAIL_SPACE)==${#FOO_NO_TRAIL_SPACE}"
# > length(FOO_NO_TRAIL_SPACE)==15

Comment supprimer les deux espaces de début et de fin seds:

FOO=' test test test '
FOO_NO_EXTERNAL_SPACE="$(echo -e "${FOO}" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"
echo -e "FOO_NO_EXTERNAL_SPACE='${FOO_NO_EXTERNAL_SPACE}'"
# > FOO_NO_EXTERNAL_SPACE='test test test'
echo -e "length(FOO_NO_EXTERNAL_SPACE)==${#FOO_NO_EXTERNAL_SPACE}"
# > length(FOO_NO_EXTERNAL_SPACE)==14

Alternativement, si votre bash le supporte, vous pouvez remplacer echo -e "${FOO}" | sed ... avec sed ... <<<${FOO}, comme ça (pour les espaces blancs):

FOO_NO_TRAIL_SPACE="$(sed -e 's/[[:space:]]*$//' <<<${FOO})"

811



Une réponse simple est:

echo "   lol  " | xargs

Xargs fera la coupe pour vous. C'est une commande / programme, pas de paramètres, retourne la chaîne rognée, facile comme ça!

Note: cela ne supprime pas les espaces internes "foo bar" reste le même. Cela ne devient pas "foobar".


644



Il existe une solution qui utilise uniquement les built-ins Bash appelés caractères génériques:

var="    abc    "
# remove leading whitespace characters
var="${var#"${var%%[![:space:]]*}"}"
# remove trailing whitespace characters
var="${var%"${var##*[![:space:]]}"}"   
echo "===$var==="

Voici la même chose dans une fonction:

trim() {
    local var="$*"
    # remove leading whitespace characters
    var="${var#"${var%%[![:space:]]*}"}"
    # remove trailing whitespace characters
    var="${var%"${var##*[![:space:]]}"}"   
    echo -n "$var"
}

Vous passez la chaîne à découper sous forme de guillemets. par exemple.:

trim "   abc   "

Une bonne chose à propos de cette solution est qu'elle fonctionnera avec n'importe quel shell compatible POSIX.

Référence


247



Bash a une fonction appelée expansion de paramètre, qui, entre autres choses, permet le remplacement de la chaîne sur la base de soi-disant modèles (Les modèles ressemblent à des expressions régulières, mais il existe des différences et des limites fondamentales). [La ligne originale de flussence: Bash a des expressions régulières, mais elles sont bien cachées:]

Ce qui suit montre comment supprimer tout espace blanc (même de l'intérieur) à partir d'une valeur variable.

$ var='abc def'
$ echo "$var"
abc def
# Note: flussence's original expression was "${var/ /}", which only replaced the *first* space char., wherever it appeared.
$ echo -n "${var//[[:space:]]/}"
abcdef

62



Vous pouvez couper simplement avec echo:

foo=" qsdqsd qsdqs q qs   "

# Not trimmed
echo \'$foo\'

# Trim
foo=`echo $foo`

# Trimmed
echo \'$foo\'

36



Dénudez un espace avant et un espace arrière

trim()
{
    local trimmed="$1"

    # Strip leading space.
    trimmed="${trimmed## }"
    # Strip trailing space.
    trimmed="${trimmed%% }"

    echo "$trimmed"
}

Par exemple:

test1="$(trim " one leading")"
test2="$(trim "one trailing ")"
test3="$(trim " one leading and one trailing ")"
echo "'$test1', '$test2', '$test3'"

Sortie:

'one leading', 'one trailing', 'one leading and one trailing'

Bande tout espaces avant et arrière

trim()
{
    local trimmed="$1"

    # Strip leading spaces.
    while [[ $trimmed == ' '* ]]; do
       trimmed="${trimmed## }"
    done
    # Strip trailing spaces.
    while [[ $trimmed == *' ' ]]; do
        trimmed="${trimmed%% }"
    done

    echo "$trimmed"
}

Par exemple:

test4="$(trim "  two leading")"
test5="$(trim "two trailing  ")"
test6="$(trim "  two leading and two trailing  ")"
echo "'$test4', '$test5', '$test6'"

Sortie:

'two leading', 'two trailing', 'two leading and two trailing'

31



Afin de supprimer tous les espaces du début et de la fin d'une chaîne (y compris les caractères de fin de ligne):

echo $variable | xargs echo -n

Cela supprimera également les espaces en double:

echo "  this string has a lot       of spaces " | xargs echo -n

Produit: "cette chaîne a beaucoup d'espaces"


26



De la section Guide Bash sur globbing 

Pour utiliser un extglob dans une extension de paramètre

 #Turn on extended globbing  
shopt -s extglob  
 #Trim leading and trailing whitespace from a variable  
x=${x##+([[:space:]])}; x=${x%%+([[:space:]])}  
 #Turn off extended globbing  
shopt -u extglob  

Voici la même fonctionnalité enveloppée dans une fonction (NOTE: Nécessité de citer une chaîne d'entrée passée à la fonction):

trim() {
    # Determine if 'extglob' is currently on.
    local extglobWasOff=1
    shopt extglob >/dev/null && extglobWasOff=0 
    (( extglobWasOff )) && shopt -s extglob # Turn 'extglob' on, if currently turned off.
    # Trim leading and trailing whitespace
    local var=$1
    var=${var##+([[:space:]])}
    var=${var%%+([[:space:]])}
    (( extglobWasOff )) && shopt -u extglob # If 'extglob' was off before, turn it back off.
    echo -n "$var"  # Output trimmed string.
}

Usage:

string="   abc def ghi  ";
#need to quote input-string to preserve internal white-space if any
trimmed=$(trim "$string");  
echo "$trimmed";

23



Avec les fonctionnalités de correspondance de modèle étendues de Bash activées (shopt -s extglob), vous pouvez utiliser ceci:

{trimmed##*( )}

pour supprimer une quantité arbitraire d'espaces de début.


22