1144

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

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

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

  • 有没有一种简单的方法可以去除空格$var(比如trim()PHP中)?

或者

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

我可以使用sedAWK,但我想有一个更优雅的解决方案来解决这个问题。

4

45 回答 45

1307

一个简单的答案是:

echo "   lol  " | xargs

Xargs将为您进行修剪。这是一个命令/程序,没有参数,返回修剪后的字符串,就这么简单!

注意:这不会删除所有内部空间,因此"foo bar"保持不变;它不会变成"foobar". 但是,多个空格会被压缩为单个空格,所以"foo bar"会变成"foo bar". 此外,它不会删除行尾字符。

于 2012-10-19T11:52:21.263 回答
1121

让我们定义一个包含前导、尾随和中间空格的变量:

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

如何删除所有空格(用[:space:]in表示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

如何仅删除前导空格:

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

如何仅删除尾随空格:

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

如何同时删除前导空格和尾随空格——链接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

或者,如果您的 bash 支持它,您可以替换echo -e "${FOO}" | sed ...sed ... <<<${FOO},如下所示(用于尾随空格):

FOO_NO_TRAIL_SPACE="$(sed -e 's/[[:space:]]*$//' <<<${FOO})"
于 2010-07-12T21:31:19.300 回答
445

有一个解决方案只使用称为通配符的 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 一起工作。

参考

于 2010-07-28T10:37:08.883 回答
102

Bash 有一个称为参数扩展的功能,除其他外,它允许基于所谓的模式替换字符串(模式类似于正则表达式,但存在根本的区别和限制)。[flussence 的原话:Bash 有正则表达式,但它们隐藏得很好:]

下面演示如何从变量值中删除所有空白(甚至是内部空白)。

$ 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
于 2008-12-15T21:37:41.893 回答
90

为了删除字符串开头和结尾的所有空格(包括行尾字符):

echo $variable | xargs echo -n

这也将删除重复的空格:

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

Produces: 'this string has a lot of spaces'
于 2016-12-04T18:28:09.813 回答
66

去掉一个前导和一个尾随空格

trim()
{
    local trimmed="$1"

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

    echo "$trimmed"
}

例如:

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

输出:

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

去除所有前导和尾随空格

trim()
{
    local trimmed="$1"

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

    echo "$trimmed"
}

例如:

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

输出:

'two leading', 'two trailing', 'two leading and two trailing'
于 2009-11-05T21:41:59.457 回答
47

来自 Bash Guide 的globbing部分

在参数扩展中使用 extglob

 #Turn on extended globbing  
shopt -s extglob  
 #Trim leading and trailing whitespace from a variable  
x=${x##+([[:space:]])}; x=${x%%+([[:space:]])}  
 #Turn off extended globbing  
shopt -u extglob  

这是包装在函数中的相同功能(注意:需要引用传递给函数的输入字符串):

trim() {
    # Determine if 'extglob' is currently on.
    local extglobWasOff=1
    shopt extglob >/dev/null && extglobWasOff=0 
    (( extglobWasOff )) && shopt -s extglob # Turn 'extglob' on, if currently turned off.
    # Trim leading and trailing whitespace
    local var=$1
    var=${var##+([[:space:]])}
    var=${var%%+([[:space:]])}
    (( extglobWasOff )) && shopt -u extglob # If 'extglob' was off before, turn it back off.
    echo -n "$var"  # Output trimmed string.
}

用法:

string="   abc def ghi  ";
#need to quote input-string to preserve internal white-space if any
trimmed=$(trim "$string");  
echo "$trimmed";

如果我们改变函数以在子shell中执行,我们不必担心检查extglob的当前shell选项,我们可以设置它而不影响当前shell。这极大地简化了功能。我还“就地”更新了位置参数,所以我什至不需要局部变量

trim() {
    shopt -s extglob
    set -- "${1##+([[:space:]])}"
    printf "%s" "${1%%+([[:space:]])}" 
}

所以:

$ s=$'\t\n \r\tfoo  '
$ shopt -u extglob
$ shopt extglob
extglob         off
$ printf ">%q<\n" "$s" "$(trim "$s")"
>$'\t\n \r\tfoo  '<
>foo<
$ shopt extglob
extglob         off
于 2011-09-20T14:13:59.380 回答
46

您可以简单地修剪echo

foo=" qsdqsd qsdqs q qs   "

# Not trimmed
echo \'$foo\'

# Trim
foo=`echo $foo`

# Trimmed
echo \'$foo\'
于 2013-03-14T00:05:20.560 回答
31

我一直用 sed

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

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

于 2008-12-15T21:28:48.120 回答
28

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

{trimmed##*( )}

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

于 2010-06-10T14:54:09.287 回答
25

您可以使用以下命令删除换行符tr

var=`hg st -R "$path" | tr -d '\n'`
if [ -n $var ]; then
    echo $var
done
于 2008-12-15T21:42:26.097 回答
21
# Trim whitespace from both ends of specified parameter

trim () {
    read -rd '' $1 <<<"${!1}"
}

# Unit test for trim()

test_trim () {
    local foo="$1"
    trim foo
    test "$foo" = "$2"
}

test_trim hey hey &&
test_trim '  hey' hey &&
test_trim 'ho  ' ho &&
test_trim 'hey ho' 'hey ho' &&
test_trim '  hey  ho  ' 'hey  ho' &&
test_trim $'\n\n\t hey\n\t ho \t\n' $'hey\n\t ho' &&
test_trim $'\n' '' &&
test_trim '\n' '\n' &&
echo passed
于 2012-01-25T08:27:25.343 回答
18

这就是我所做的并且完美且如此简单:

the_string="        test"
the_string=`echo $the_string`
echo "$the_string"

输出:

test
于 2020-11-02T15:24:38.217 回答
16

有很多答案,但我仍然相信我刚刚编写的脚本值得一提,因为:

  • 它已在 shell bash/dash/busybox shell 中成功测试
  • 它非常小
  • 它不依赖于外部命令,也不需要分叉(->快速和低资源使用)
  • 它按预期工作:
    • 它从头到尾删除所有空格和制表符,但仅此而已
    • 重要:它不会从字符串中间删除任何东西(许多其他答案都会这样做),甚至换行符也会保留
    • 特殊:"$*"使用一个空格连接多个参数。如果您只想修剪和输出第一个参数,请"$1"改用
    • 如果匹配文件名模式等没有任何问题

剧本:

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<
于 2015-10-20T23:32:01.833 回答
13

如果您已shopt -s extglob启用,那么以下是一个简洁的解决方案。

这对我有用:

text="   trim my edges    "

trimmed=$text
trimmed=${trimmed##+( )} #Remove longest matching series of spaces from the front
trimmed=${trimmed%%+( )} #Remove longest matching series of spaces from the back

echo "<$trimmed>" #Adding angle braces just to make it easier to confirm that all spaces are removed

#Result
<trim my edges>

将其放在更少的行上以获得相同的结果:

text="    trim my edges    "
trimmed=${${text##+( )}%%+( )}
于 2014-09-11T19:55:39.693 回答
12
# Strip leading and trailing white space (new line inclusive).
trim(){
    [[ "$1" =~ [^[:space:]](.*[^[:space:]])? ]]
    printf "%s" "$BASH_REMATCH"
}

或者

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

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

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

或者

# 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]}"
}

或者

# 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")"
}

或者

建立在 moskit 的 expr 灵魂之上...

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

或者

# 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")")"
}
于 2017-05-01T20:09:26.933 回答
11

您可以使用 old-school tr。例如,这将返回 git 存储库中已修改文件的数量,去掉空格。

MYVAR=`git ls-files -m|wc -l|tr -d ' '`
于 2009-11-27T09:49:36.157 回答
11

使用 AWK:

echo $var | awk '{gsub(/^ +| +$/,"")}1'
于 2009-11-05T23:48:51.337 回答
8

我见过脚本只是使用变量赋值来完成这项工作:

$ xyz=`echo -e 'foo \n bar'`
$ echo $xyz
foo bar

空白会自动合并和修剪。必须小心 shell 元字符(潜在的注入风险)。

我还建议始终在 shell 条件中使用双引号变量替换:

if [ -n "$var" ]; then

因为变量中的 -o 或其他内容可能会修改您的测试参数。

于 2008-12-15T21:57:01.403 回答
8

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

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

/替换//字符串中第一次出现和所有出现的空格。即所有空白都被替换为 - 没有

于 2013-05-29T12:03:41.373 回答
8

我会简单地使用 sed:

function trim
{
    echo "$1" | sed -n '1h;1!H;${;g;s/^[ \t]*//g;s/[ \t]*$//g;p;}'
}

a) 单行字符串的使用示例

string='    wordA wordB  wordC   wordD    '
trimmed=$( trim "$string" )

echo "GIVEN STRING: |$string|"
echo "TRIMMED STRING: |$trimmed|"

输出:

GIVEN STRING: |    wordA wordB  wordC   wordD    |
TRIMMED STRING: |wordA wordB  wordC   wordD|

b) 多行字符串的使用示例

string='    wordA
   >wordB<
wordC    '
trimmed=$( trim "$string" )

echo -e "GIVEN STRING: |$string|\n"
echo "TRIMMED STRING: |$trimmed|"

输出:

GIVEN STRING: |    wordAA
   >wordB<
wordC    |

TRIMMED STRING: |wordAA
   >wordB<
wordC|

c)最后说明:
如果您不喜欢使用函数,对于单行字符串,您可以简单地使用“更容易记住”的命令,例如:

echo "$string" | sed -e 's/^[ \t]*//' | sed -e 's/[ \t]*$//'

例子:

echo "   wordA wordB wordC   " | sed -e 's/^[ \t]*//' | sed -e 's/[ \t]*$//'

输出:

wordA wordB wordC

在多行字符串上使用上述内容也可以,但请注意,正如 GuruM 在评论中注意到的那样,它也会削减任何尾随/前导内部多个空格

string='    wordAA
    >four spaces before<
 >one space before<    '
echo "$string" | sed -e 's/^[ \t]*//' | sed -e 's/[ \t]*$//'

输出:

wordAA
>four spaces before<
>one space before<

因此,如果您介意保留这些空格,请使用我回答开头的功能!

d)对函数 trim 内使用的多行字符串的 sed 语法“查找和替换”的解释:

sed -n '
# If the first line, copy the pattern to the hold buffer
1h
# If not the first line, then append the pattern to the hold buffer
1!H
# If the last line then ...
$ {
    # Copy from the hold to the pattern buffer
    g
    # Do the search and replace
    s/^[ \t]*//g
    s/[ \t]*$//g
    # print
    p
}'
于 2012-08-27T16:52:10.523 回答
7
var='   a b c   '
trimmed=$(echo $var)
于 2013-04-01T11:26:14.457 回答
6

赋值忽略前导和尾随空格,因此可用于修剪:

$ var=`echo '   hello'`; echo $var
hello
于 2010-10-01T11:25:52.113 回答
6

这是一个修剪和规范化空白的 trim() 函数

#!/bin/bash
function trim {
    echo $*
}

echo "'$(trim "  one   two    three  ")'"
# 'one two three'

还有另一个使用正则表达式的变体。

#!/bin/bash
function trim {
    local trimmed="$@"
    if [[ "$trimmed" =~ " *([^ ].*[^ ]) *" ]]
    then 
        trimmed=${BASH_REMATCH[1]}
    fi
    echo "$trimmed"
}

echo "'$(trim "  one   two    three  ")'"
# 'one   two    three'
于 2011-06-08T16:32:30.403 回答
6

这是我见过的最简单的方法。它只使用 Bash,只有几行,正则表达式很简单,它匹配所有形式的空格:

if [[ "$test" =~ ^[[:space:]]*([^[:space:]].*[^[:space:]])[[:space:]]*$ ]]
then 
    test=${BASH_REMATCH[1]}
fi

这是一个用于测试它的示例脚本:

test=$(echo -e "\n \t Spaces and tabs and newlines be gone! \t  \n ")

echo "Let's see if this works:"
echo
echo "----------"
echo -e "Testing:${test} :Tested"  # Ugh!
echo "----------"
echo
echo "Ugh!  Let's fix that..."

if [[ "$test" =~ ^[[:space:]]*([^[:space:]].*[^[:space:]])[[:space:]]*$ ]]
then 
    test=${BASH_REMATCH[1]}
fi

echo
echo "----------"
echo -e "Testing:${test}:Tested"  # "Testing:Spaces and tabs and newlines be gone!"
echo "----------"
echo
echo "Ah, much better."
于 2014-04-28T04:25:24.117 回答
6

要从左到第一个单词删除空格和制表符,请输入:

echo "     This is a test" | sed "s/^[ \t]*//"

cyberciti.biz/tips/delete-leading-spaces-from-front-of-each-word.html

于 2012-07-06T05:46:33.500 回答
5

这不存在不需要的 globbing 的问题,而且内部空白未修改(假设$IFS设置为默认值,即' \t\n')。

它读取到第一个换行符(并且不包括它)或字符串的末尾,以先到者为准,并去除前导和尾随空格和\t字符的任何混合。如果您想保留多行(并且还要去除前导和尾随换行符),请read -r -d '' var << eof改用;但是请注意,如果您的输入恰好包含\neof,它将在之前被切断。(其他形式的空格,即\r\f\v不会被去除,即使您将它们添加到 $IFS 也是如此。)

read -r var << eof
$var
eof
于 2011-11-02T22:39:05.280 回答
4

将空格删除为一个空格:

(text) | fmt -su
于 2010-06-13T10:04:32.673 回答
4

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
于 2011-06-07T19:29:04.483 回答
4

trim() 删除空格(和制表符,不可打印的字符;为简单起见,我只考虑空格)。我的解决方案版本:

var="$(hg st -R "$path")" # I often like to enclose shell output in double quotes
var="$(echo "${var}" | sed "s/\(^ *\| *\$\)//g")" # This is my suggestion
if [ -n "$var" ]; then
 echo "[${var}]"
fi

'sed' 命令只修剪前导和尾随空格,但它也可以通过管道传送到第一个命令,从而导致:

var="$(hg st -R "$path" | sed "s/\(^ *\| *\$\)//g")"
if [ -n "$var" ]; then
 echo "[${var}]"
fi
于 2012-06-15T22:36:31.187 回答
4

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
于 2014-08-07T23:16:12.110 回答
4

利用:

trim() {
    local orig="$1"
    local trmd=""
    while true;
    do
        trmd="${orig#[[:space:]]}"
        trmd="${trmd%[[:space:]]}"
        test "$trmd" = "$orig" && break
        orig="$trmd"
    done
    printf -- '%s\n' "$trmd"
}
  • 它适用于各种空白,包括换行符,
  • 它不需要修改shopt。
  • 它保留内部空格,包括换行符。

单元测试(用于人工审核):

#!/bin/bash

. trim.sh

enum() {
    echo "   a b c"
    echo "a b c   "
    echo "  a b c "
    echo " a b c  "
    echo " a  b c  "
    echo " a  b  c  "
    echo " a      b  c  "
    echo "     a      b  c  "
    echo "     a  b  c  "
    echo " a  b  c      "
    echo " a  b  c      "
    echo " a N b  c  "
    echo "N a N b  c  "
    echo " Na  b  c  "
    echo " a  b  c N "
    echo " a  b  c  N"
}

xcheck() {
    local testln result
    while IFS='' read testln;
    do
        testln=$(tr N '\n' <<<"$testln")
        echo ": ~~~~~~~~~~~~~~~~~~~~~~~~~ :" >&2
        result="$(trim "$testln")"
        echo "testln='$testln'" >&2
        echo "result='$result'" >&2
    done
}

enum | xcheck
于 2015-07-12T20:55:59.333 回答
4

我必须测试命令的结果(数字),但结果的变量似乎包含空格和一些不可打印的字符。因此,即使在“修剪”之后,比较也是错误的。我通过从变量中提取数字部分来解决它:

numerical_var=$(echo ${var_with_result_from_command} | grep -o "[0-9]*")
于 2019-06-28T10:35:48.527 回答
3

我发现我需要从杂乱的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'

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

于 2012-02-03T23:57:41.667 回答
3

使用这个简单的 Bash参数扩展

$ x=" a z     e r ty "
$ echo "START[${x// /}]END"
START[azerty]END
于 2012-06-03T19:29:06.440 回答
3

这修剪了前端和末端的多个空间

whatever=${whatever%% *}

whatever=${whatever#* }

于 2010-10-11T13:17:37.220 回答
3

我创建了以下函数。我不确定 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"`
于 2010-11-15T02:23:05.823 回答
2
var="  a b  "
echo "$(set -f; echo $var)"

>a b
于 2013-02-28T00:35:37.830 回答
2
#!/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]
#[]
于 2011-12-02T02:26:32.027 回答
2

利用:

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

我相信它删除了前导和尾随空格,是最基本的解决方案。不是 Bash 内置的,但 'expr' 是 coreutils 的一部分,因此至少不需要像sedAWK这样的独立实用程序。

于 2014-03-06T21:41:13.213 回答
1

另一个带有单元测试的解决方案,它从标准输入中修剪$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+"$@"}
}
于 2011-09-21T11:04:17.173 回答
1

数组分配在内部字段分隔符(默认为空格/制表符/换行符)上扩展其参数拆分。

words=($var)
var="${words[@]}"
于 2021-03-18T14:28:33.620 回答
1

“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 $?
}
于 2021-05-06T12:36:40.693 回答
-3

虽然它不是严格意义上的 Bash,但它会做你想做的事情以及更多:

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

如果您也想将其设为小写,请执行以下操作:

php -r '$x = trim("  Hi There  "); $x = strtolower($x) ; echo $x;'
于 2013-01-07T13:55:13.183 回答
-4
#Execute this script with the string argument passed in double quotes !! 
#var2 gives the string without spaces.
#$1 is the string passed in double quotes
#!/bin/bash
var2=`echo $1 | sed 's/ \+//g'`
echo $var2
于 2013-03-20T04:37:32.530 回答