[string] Cómo recortar el espacio en blanco de una variable Bash?



14 Answers

Una respuesta simple es:

echo "   lol  " | xargs

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

Nota: esto no elimina los espacios internos por lo que "foo bar" permanece igual. NO se convierte en "foobar" .

Question

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 forma simple de quitar espacio en blanco de $var (como 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.




I found that I needed to add some code from a messy sdiff output in order to clean it up:

sdiff -s column1.txt column2.txt | grep -F '<' | cut -f1 -d"<" > c12diff.txt 
sed -n 1'p' c12diff.txt | sed 's/ *$//g' | tr -d '\n' | tr -d '\t'

This removes the trailing spaces and other invisible characters.




This will remove all the whitespaces from your String,

 VAR2="${VAR2//[[:space:]]/}"

/ replaces the first occurrence and // all occurrences of whitespaces in the string. Ie all white spaces get replaced by – nothing




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'

Pelar todos los 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'



# Strip leading and trailing white space (new line inclusive).
trim(){
    [[ "$1" =~ ^[[:space:]]*(.*[^[:space:]])[[:space:]]*$ ]]
    printf "%s" "${BASH_REMATCH[1]}"
}

O

# Strip leading white space (new line inclusive).
ltrim(){
    [[ "$1" =~ ^[[:space:]]*(.*[^[:space:]]) ]]
    printf "%s" "${BASH_REMATCH[1]}"
}

# Strip trailing white space (new line inclusive).
rtrim(){
    [[ "$1" =~ ^[[:space:]]*(.*[^[:space:]])[[:space:]]*$ ]]
    printf "%s" "${BASH_REMATCH[1]}"
}

# Strip leading and trailing white space (new line inclusive).
trim(){
    printf "%s" "$(rtrim "$(ltrim "$1")")"
}

O

# Strip leading and trailing specified characters.  ex: str=$(trim "$str" $'\n a')
trim(){
    if [ "$2" ]; then
        trim_chrs="$2"
    else
        trim_chrs="[:space:]"
    fi

    [[ "$1" =~ ^["$trim_chrs"]*(.*[^"$trim_chrs"])["$trim_chrs"]*$ ]]
    printf "%s" "${BASH_REMATCH[1]}"
}

O

# Strip leading specified characters.  ex: str=$(ltrim "$str" $'\n a')
ltrim(){
    if [ "$2" ]; then
        trim_chrs="$2"
    else
        trim_chrs="[:space:]"
    fi

    [[ "$1" =~ ^["$trim_chrs"]*(.*[^"$trim_chrs"]) ]]
    printf "%s" "${BASH_REMATCH[1]}"
}

# Strip trailing specified characters.  ex: str=$(rtrim "$str" $'\n a')
rtrim(){
    if [ "$2" ]; then
        trim_chrs="$2"
    else
        trim_chrs="[:space:]"
    fi

    [[ "$1" =~ ^(.*[^"$trim_chrs"])["$trim_chrs"]*$ ]]
    printf "%s" "${BASH_REMATCH[1]}"
}

# Strip leading and trailing specified characters.  ex: str=$(trim "$str" $'\n a')
trim(){
    printf "%s" "$(rtrim "$(ltrim "$1" "$2")" "$2")"
}

O

Basándose en la exlusión de moskit ...

# Strip leading and trailing white space (new line inclusive).
trim(){
    printf "%s" "`expr "$1" : "^[[:space:]]*\(.*[^[:space:]]\)[[:space:]]*$"`"
}

O

# Strip leading white space (new line inclusive).
ltrim(){
    printf "%s" "`expr "$1" : "^[[:space:]]*\(.*[^[:space:]]\)"`"
}

# Strip trailing white space (new line inclusive).
rtrim(){
    printf "%s" "`expr "$1" : "^\(.*[^[:space:]]\)[[:space:]]*$"`"
}

# Strip leading and trailing white space (new line inclusive).
trim(){
    printf "%s" "$(rtrim "$(ltrim "$1")")"
}



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'




Siempre lo hice con sed

  var=`hg st -R "$path" | sed -e 's/  *$//'`

Si hay una solución más elegante, espero que alguien la publique.




Puedes usar el tr vieja escuela. Por ejemplo, esto devuelve la cantidad de archivos modificados en un repositorio de git, espacios en blanco despojados.

MYVAR=`git ls-files -m|wc -l|tr -d ' '`



I created the following functions. I am not sure how portable printf is, but the beauty of this solution is you can specify exactly what is "white space" by adding more character codes.

    iswhitespace()
    {
        n=`printf "%d\n" "'$1'"`
        if (( $n != "13" )) && (( $n != "10" )) && (( $n != "32" )) && (( $n != "92" )) && (( $n != "110" )) && (( $n != "114" )); then
            return 0
        fi
        return 1
    }

    trim()
    {
        i=0
        str="$1"
        while (( i < ${#1} ))
        do
            char=${1:$i:1}
            iswhitespace "$char"
            if [ "$?" -eq "0" ]; then
                str="${str:$i}"
                i=${#1}
            fi
            (( i += 1 ))
        done
        i=${#str}
        while (( i > "0" ))
        do
            (( i -= 1 ))
            char=${str:$i:1}
            iswhitespace "$char"
            if [ "$?" -eq "0" ]; then
                (( i += 1 ))
                str="${str:0:$i}"
                i=0
            fi
        done
        echo "$str"
    }

#Call it like so
mystring=`trim "$mystring"`



Assignments ignore leading and trailing whitespace and as such can be used to trim:

$ var=`echo '   hello'`; echo $var
hello



#!/bin/bash

function trim
{
    typeset trimVar
    eval trimVar="\${$1}"
    read trimVar << EOTtrim
    $trimVar
EOTtrim
    eval $1=\$trimVar
}

# Note that the parameter to the function is the NAME of the variable to trim, 
# not the variable contents.  However, the contents are trimmed.


# Example of use:
while read aLine
do
    trim aline
    echo "[${aline}]"
done < info.txt



# File info.txt contents:
# ------------------------------
# ok  hello there    $
#    another  line   here     $
#and yet another   $
#  only at the front$
#$



# Output:
#[ok  hello there]
#[another  line   here]
#[and yet another]
#[only at the front]
#[]



Bash tiene una característica llamada expansión de parámetros , que, entre otras cosas, permite el reemplazo de cadenas en base a los llamados 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 todo el espacio en blanco (incluso desde el interior) de un valor de 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



Puede eliminar nuevas líneas con tr :

var=`hg st -R "$path" | tr -d '\n'`
if [ -n $var ]; then
    echo $var
done



This does not have the problem with unwanted globbing, also, interior white-space is unmodified (assuming that $IFS is set to the default, which is ' \t\n' ).

It reads up to the first newline (and doesn't include it) or the end of string, whichever comes first, and strips away any mix of leading and trailing space and \t characters. If you want to preserve multiple lines (and also strip leading and trailing newlines), use read -r -d '' var << eof instead; note, however, that if your input happens to contain \neof , it will be cut off just before. (Other forms of white space, namely \r , \f , and \v , are not stripped, even if you add them to $IFS.)

read -r var << eof
$var
eof



var='   a b c   '
trimmed=$(echo $var)





Related