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

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

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

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

or

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

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


当前回答

使用Bash的扩展模式匹配功能(shopt -s extglob),你可以这样使用:

修剪{# # * ()}

删除任意数量的前导空格。

其他回答

答案有很多,但我仍然认为我刚刚写的剧本值得一提,因为:

it was successfully tested in the shells bash/dash/busybox shell it is extremely small it doesn't depend on external commands and doesn't need to fork (->fast and low resource usage) it works as expected: it strips all spaces and tabs from beginning and end, but not more important: it doesn't remove anything from the middle of the string (many other answers do), even newlines will remain special: the "$*" joins multiple arguments using one space. if you want to trim & output only the first argument, use "$1" instead if doesn't have any problems with matching file name patterns etc

脚本:

trim() {
  local s2 s="$*"
  until s2="${s#[[:space:]]}"; [ "$s2" = "$s" ]; do s="$s2"; done
  until s2="${s%[[:space:]]}"; [ "$s2" = "$s" ]; do s="$s2"; done
  echo "$s"
}

用法:

mystring="   here     is
    something    "
mystring=$(trim "$mystring")
echo ">$mystring<"

输出:

>here     is
    something<

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.

你可以使用tr删除换行符:

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

Python有一个函数strip(),它的工作原理与PHP的trim()相同,因此我们可以使用一点内联Python来创建一个易于理解的实用程序:

alias trim='python -c "import sys; sys.stdout.write(sys.stdin.read().strip())"'

这将删除开头和结尾的空白(包括换行符)。

$ x=`echo -e "\n\t   \n" | trim`
$ if [ -z "$x" ]; then echo hi; fi
hi

"trim"函数删除所有水平空白:

ltrim () {
    if [[ $# -eq 0 ]]; then cat; else printf -- '%s\n' "$@"; fi | perl -pe 's/^\h+//g'
    return $?
}

rtrim () {
    if [[ $# -eq 0 ]]; then cat; else printf -- '%s\n' "$@"; fi | perl -pe 's/\h+$//g'
    return $?
}

trim () {
    ltrim "$@" | rtrim
    return $?
}