我有一个shell脚本与这段代码:

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

但是条件代码总是执行,因为hg st总是打印至少一个换行符。

是否有一个简单的方法从$var中剥离空白(如PHP中的trim())?

or

有没有处理这个问题的标准方法?

我可以使用sed或AWK,但我认为有一个更优雅的解决方案来解决这个问题。


当前回答

我创建了以下函数。我不确定printf的可移植性如何,但这个解决方案的美妙之处在于,您可以通过添加更多字符代码来指定什么是“空白”。

    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"`

其他回答

Read已经修整了空白,所以在bash中你可以这样做:

$ read foo <<< "   foo  bar   two spaces follow   "
$ echo ".$foo."
.foo  bar   two spaces follow.

POSIX兼容的版本稍长一些

$ read foo << END
   foo  bar   two spaces follow   
END
$ echo ".$foo."
.foo  bar   two spaces follow.

有一个解决方案只使用Bash内置的通配符:

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

下面是同样的包装在一个函数中:

trim() {
    local var="$*"
    # remove leading whitespace characters
    var="${var#"${var%%[![:space:]]*}"}"
    # remove trailing whitespace characters
    var="${var%"${var##*[![:space:]]}"}"
    printf '%s' "$var"
}

你传递要以引号形式修剪的字符串,例如:

trim "   abc   "

这个解决方案的一个优点是它可以与任何posix兼容的shell一起工作。

参考

从Bash变量中删除前导和尾随空格(原始源代码)

Use:

var=`expr "$var" : "^\ *\(.*[^ ]\)\ *$"`

它去掉了开头和结尾的空格,我认为这是最基本的解决方案。不是Bash内置的,但'expr'是coreutils的一部分,所以至少不需要像sed或AWK这样的独立实用程序。

当IFS变量被设置为其他变量时,我需要从脚本中删除空白。依赖Perl实现了这个目的:

# trim() { echo $1; } # This doesn't seem to work, as it's affected by IFS

trim() { echo "$1" | perl -p -e 's/^\s+|\s+$//g'; }

strings="after --> , <-- before,  <-- both -->  "

OLD_IFS=$IFS
IFS=","
for str in ${strings}; do
  str=$(trim "${str}")
  echo "str= '${str}'"
done
IFS=$OLD_IFS

您可以使用老式的tr。例如,它返回git存储库中已修改文件的数量,删除空白。

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