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

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

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

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

or

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

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


当前回答

这将删除字符串中的所有空格,

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

/替换字符串中第一次出现的空格和//所有出现的空格。也就是说,所有的空格都被- nothing取代

其他回答

还有一个单元测试的解决方案,它从stdin中删除$IFS,并适用于任何输入分隔符(甚至$'\0'):

ltrim()
{
    # Left-trim $IFS from stdin as a single line
    # $1: Line separator (default NUL)
    local trimmed
    while IFS= read -r -d "${1-}" -u 9
    do
        if [ -n "${trimmed+defined}" ]
        then
            printf %s "$REPLY"
        else
            printf %s "${REPLY#"${REPLY%%[!$IFS]*}"}"
        fi
        printf "${1-\x00}"
        trimmed=true
    done 9<&0

    if [[ $REPLY ]]
    then
        # No delimiter at last line
        if [ -n "${trimmed+defined}" ]
        then
            printf %s "$REPLY"
        else
            printf %s "${REPLY#"${REPLY%%[!$IFS]*}"}"
        fi
    fi
}

rtrim()
{
    # Right-trim $IFS from stdin as a single line
    # $1: Line separator (default NUL)
    local previous last
    while IFS= read -r -d "${1-}" -u 9
    do
        if [ -n "${previous+defined}" ]
        then
            printf %s "$previous"
            printf "${1-\x00}"
        fi
        previous="$REPLY"
    done 9<&0

    if [[ $REPLY ]]
    then
        # No delimiter at last line
        last="$REPLY"
        printf %s "$previous"
        if [ -n "${previous+defined}" ]
        then
            printf "${1-\x00}"
        fi
    else
        last="$previous"
    fi

    right_whitespace="${last##*[!$IFS]}"
    printf %s "${last%$right_whitespace}"
}

trim()
{
    # Trim $IFS from individual lines
    # $1: Line separator (default NUL)
    ltrim ${1+"$@"} | rtrim ${1+"$@"}
}

我总是用sed来做

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

如果有更优雅的解决方案,我希望有人能发布出来。

虽然它不是严格的Bash,这将做你想要的和更多:

php -r '$x = trim("  hi there  "); echo $x;'

如果你也想让它小写,可以这样做:

php -r '$x = trim("  Hi There  "); $x = strtolower($x) ; echo $x;'

我发现我需要从混乱的sdiff输出中添加一些代码来清理它:

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'

这将删除尾随空格和其他不可见字符。

我所知道的单行用例最简单的方法是:

echo "  ABC  " | sed -e 's# \+\(.\+\) \+#\1#'

工作原理:

-e启用高级正则表达式 我使用# sed,因为我不喜欢“凌乱的库”模式,如/\////\/\\\/\/ Sed希望转义大多数正则表达式控制字符,因此所有\ 否则就是^ +(.+)+$,也就是开头的空格,一组no。1,空格在最后。 所有这些都被“第一组”所取代。

因此,ABC变成了ABC。

这应该在使用sed的最新系统上得到支持。


对于标签来说,就是这样

echo "  ABC  " | sed -e 's#[\t ]\+\(.\+\)[\t ]\+#\1#'

对于多行内容,已经需要其他答案中描述的[:space:]这样的字符类,并且可能不是所有sed实现都支持。

参考资料:Sed手册