Pregunta Cómo recortar el espacio en blanco de una variable Bash?


Tengo un script de shell con este código:

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

Pero el código condicional siempre se ejecuta, porque hg st siempre imprime al menos un carácter de nueva línea.

  • ¿Hay una manera simple de quitar espacio en blanco de $var (me gusta trim() en PHP)?

o

  • ¿Hay una forma estándar de lidiar con este problema?

Podría usar sed o AWK, pero me gustaría pensar que hay una solución más elegante para este problema.


653
2017-10-20 23:32


origen


Respuestas:


Definamos una variable que contenga espacios en blanco iniciales, finales e intermedios:

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

Cómo eliminar todos los espacios en blanco (indicado por [:space:] en 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

Cómo eliminar espacios en blanco iniciales solamente:

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

Cómo eliminar espacios en blanco finales solo:

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

Cómo eliminar los espacios iniciales y finales: encadene la 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

Alternativamente, si tu bash lo admite, puedes reemplazar echo -e "${FOO}" | sed ... con sed ... <<<${FOO}, como tal (para espacios en blanco al final):

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

811



Una respuesta simple es:

echo "   lol  " | xargs

Xargs hará el recorte para usted. Es un comando / programa, sin parámetros, devuelve la cadena recortada, ¡así de fácil!

Nota: esto no elimina los espacios internos por lo "foo bar" Se mantiene igual. NO se convierte "foobar".


644



Hay una solución que solo usa Bash built-ins llamado comodines:

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

Aquí está lo mismo envuelto en una función:

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

Pasa la cuerda para recortarla en forma de cita. p.ej.:

trim "   abc   "

Algo bueno de esta solución es que funcionará con cualquier shell que cumpla con POSIX.

Referencia


247



Bash tiene una función llamada expansión de parámetros, que, entre otras cosas, permite el reemplazo de cadenas en base a los denominados patrones (los patrones se parecen a las expresiones regulares, pero existen diferencias y limitaciones fundamentales). [La línea original de flussence: Bash tiene expresiones regulares, pero están bien escondidas:]

A continuación, se muestra cómo eliminar todas espacio en blanco (incluso desde el interior) desde un valor 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



Puedes recortar simplemente con echo:

foo=" qsdqsd qsdqs q qs   "

# Not trimmed
echo \'$foo\'

# Trim
foo=`echo $foo`

# Trimmed
echo \'$foo\'

36



Pele un espacio de entrada y uno de salida

trim()
{
    local trimmed="$1"

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

    echo "$trimmed"
}

Por ejemplo:

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

Salida:

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

Tira todas espacios iniciales y finales

trim()
{
    local trimmed="$1"

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

    echo "$trimmed"
}

Por ejemplo:

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

Salida:

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

31



Para eliminar todos los espacios del principio y el final de una cadena (incluidos los caracteres de fin de línea):

echo $variable | xargs echo -n

Esto eliminará espacios duplicados también:

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

Produce: 'esta cadena tiene muchos espacios'


26