当前位置:  开发笔记 > 编程语言 > 正文

如何从Bash变量中修剪空格?

如何解决《如何从Bash变量中修剪空格?》经验,为你挑选了25个好方法。

我有一个包含以下代码的shell脚本:

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

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

是否有一种简单的方法可以从中删除空格$var(比如trim()在PHP中)?

要么

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

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



1> 小智..:

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

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


要概括处理_all_形式的空格的解决方案,用`[[:space:]]`替换`tr`和`sed`命令中的空格字符.请注意,`sed`方法仅适用于_single-line_输入.对于使用多行输入并使用bash内置功能的方法,请参阅@bashfu和@GuruM的答案.@Nicholas Sushkin解决方案的通用内联版本看起来像这样:`trimmed = $([["test test test"=〜[[:space:]]*([^ [:space:]] | [^ [ :space:]].*[^ [:space:]])[[:space:]]*]]; echo -n"$ {BASH_REMATCH [1]}")`
如果你经常这样做,附加`alias trim ="sed -e's/^ [[:space:]]*// g'-e's/[[:space:]]*\$ // g' "`你的`〜/ .profile`允许你使用`echo $ SOMEVAR | trim`和`cat somefile | trim`.

2> makevoid..:

一个简单的答案是:

echo "   lol  " | xargs

Xargs会为你做修剪.它是一个命令/程序,没有参数,返回修剪过的字符串,就这么简单!

注意:这不会删除内部空间,因此"foo bar"保持不变.它不会成为"foobar".


这是不好的.1.它将`a b`变成'a b`.更重要的是:它会将"a"b"c'd'e"变成"abcde".3.甚至更多:它会在'a"b`等上失败.
尼斯.这非常有效.我决定把它传递给`xargs echo`只是为了对我正在做的事情都很冗长,但xargs本身将默认使用echo.
不错的技巧,但要小心,你可以将它用于单行字符串,但是使用xargs设计 - 它不会仅仅使用多行管道内容进行调整.sed是你的朋友.
xargs的唯一问题是它会引入一个换行符,如果你想保持换行符,我会推荐`sed's/*$''作为替代.你可以看到`xargs`换行符:`echo -n"hey thiss"| xargs | hexdump`你会注意到'0a73````是换行符.如果你对`sed`做同样的事情:`echo -n"嘿thiss"| sed's/*$ //'| hexdump`你会看到'0073`,没有新行.
小心; 如果字符串到xargs包含多余的空格,这将会破坏.就像"这是一个论点".xargs将分为四个.
我一直在使用xargs来修剪简单的字符串,直到我发现它在带有单引号或多个内部空格的字符串上失败(如上所述).我不推荐这种方法.
修剪简单的单字符串时,这是一个非常快速的解决方案.我使用它来删除sqlite的-line输出,其中列名称无用于填充脚本.

3> 小智..:

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

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

这里包含在函数中:

trim() {
    local var="$*"
    # remove leading whitespace characters
    var="${var#"${var%%[![:space:]]*}"}"
    # remove trailing whitespace characters
    var="${var%"${var##*[![:space:]]}"}"   
    echo -n "$var"
}

您以引用的形式传递要剪裁的字符串.例如:

trim "   abc   "

这个解决方案的一个好处是它可以与任何符合POSIX的shell一起使用.

参考

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


聪明!这是我最喜欢的解决方案,因为它使用内置的bash功能.谢谢发帖!@San,它是两个嵌套的字符串修剪.例如,`s ="1 2 3"; echo \""$ {s%1 2 3}"\"`将从最后修剪所有内容,返回前导的""".使用`[![:space:]]*`对`1 2 3`进行修改,告诉它"找到第一个非空格字符,然后将其删除".使用`%%`而不是`%`使得trim-from-end操作变得贪婪.这嵌套在一个非贪婪的trim-from-start中,所以实际上,你从一开始就修剪了""".然后,交换%,#和*作为结束空格.巴姆!
比使用sed,tr等更好的解决方案,因为它更快,避免任何fork().在Cygwin上,速度的差异是数量级.
@San起初我很难过,因为我认为这些是正则表达式.他们不是.相反,这是模式匹配语法(https://www.gnu.org/software/bash/manual/html_node/Pattern-Matching.html,http://wiki.bash-hackers.org/syntax/pattern)子串删除(http://tldp.org/LDP/abs/html/string-manipulation.html).所以`$ {var %% [![:space:]]*}`说"从`var`中删除它以非空格字符开头的最长子字符串".这意味着你只剩下前导空格,你随后用`$ {var#..`删除它们.以下行(尾随)是相反的.
**这绝对是理想的解决方案。**分叉一个或多个外部进程(例如,“ awk”,“ sed”,“ tr”,“ xargs”)仅从单个字符串中删去空格基本上是疯狂的,尤其是当大多数*外壳(包括bash)*已经*开箱即用地提供本机字符串调校功能。
我没有发现任何不需要的副作用,主代码也适用于其他类似POSIX的shell.但是,在Solaris 10下,它不适用于`/ bin/sh`(仅使用`/ usr/xpg4/bin/sh`,但这不适用于通常的sh脚本).

4> 小智..:

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


`$ {var//}`删除第一个空格字符.`$ {var // /}`删除所有空格字符.仅使用此构造无法修剪前导和尾随空格.
他们是正则表达式,只是一种奇怪的方言.
或者更确切地说,它适用于var中间的空格,但不是在我尝试将其锚定在最后时.

5> rkachach..:

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

echo $variable | xargs echo -n

这将删除重复的空格:

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

产生:'这个字符串有很多空格'


基本上,xargs从字符串中删除所有分隔符.默认情况下,它使用空格作为分隔符(可以通过-d选项更改).
这是迄今为止最干净(简短易读)的解决方案.

6> 小智..:

剥去一个前导空间和一个尾随空间

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'


这将仅修剪1个空格字符.所以回声会导致''你好世界','foo bar','双方'`

7> GuruM..:

从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


正如您所观察到的,trim()仅删除前导和尾随空格.

8> 小智..:

你可以简单地修剪echo:

foo=" qsdqsd qsdqs q qs   "

# Not trimmed
echo \'$foo\'

# Trim
foo=`echo $foo`

# Trimmed
echo \'$foo\'


当`foo`包含通配符时,你试过吗?例如,`foo ="我*有一张外卡"`......惊喜!此外,这将几个连续的空间折叠成一个.
如果你这样做,这是一个很好的解决方案:1.两端不需要空格2.每个单词之间只需要一个空格3.正在使用没有通配符的受控输入.它实质上将格式错误的列表变成了一个好的列表.

9> Mooshu..:

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

{trimmed##*( )}

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



10> Paul Tomblin..:

我总是用sed完成它

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

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


领先的空白怎么样?
正则表达式匹配所有尾随空格并将其替换为空.

11> Adam Rosenfi..:

您可以删除换行符tr:

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


我不想从字符串的中间删除'\n',只是从开头或结尾.

12> flabdablet..:
# 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


trim()函数的参数是一个变量名称:请参见test_trim()中对trim()的调用。在从test_trim()调用的trim()中,$ 1扩展为foo,而$ {!1}扩展为$ foo(即,变量foo的当前内容)。在bash手册中搜索“变量间接”。
@AquariusPower不需要在单层版本的子外壳中使用echo,只需`read -rd''str <<<“ $ str”`即可。

13> gMale..:

这对我有用:

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

为了相同的结果,将它放在更少的行上:

text="    trim my edges    "
trimmed=${${text##+( )}%%+( )}



14> Daniel Alder..:

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

它在shell bash/dash/busybox shell中成功测试过

它非常小

它不依赖于外部命令,也不需要fork( - >快速和低资源使用)

它按预期工作:

它从开始和结束中删除所有空格和制表符,但不是更多

重要的是:它不会从字符串的中间删除任何东西(许多其他答案都可以),甚至换行也会保留

special:"$*"使用一个空格连接多个参数.如果要仅修剪和输出第一个参数,请"$1"改用

如果匹配文件名模式等没有任何问题

剧本:

trim() {
  local s2 s="$*"
  # note: the brackets in each of the following two lines contain one space
  # and one tab
  until s2="${s#[   ]}"; [ "$s2" = "$s" ]; do s="$s2"; done
  until s2="${s%[   ]}"; [ "$s2" = "$s" ]; do s="$s2"; done
  echo "$s"
}

用法:

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

输出:

>here     is
    something<



15> pojo..:

你可以使用老派tr.例如,这将返回git存储库中已修改文件的数量,并删除空白.

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



16> NOYB..:
# 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 soulution上......

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



17> MykennaC..:

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

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

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

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

if [ -n "$var" ]; then

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


这是`$ xyz`与`echo`的不加引用的用法,它使空白合并,_not_变量赋值.要将修剪后的值存储在示例中的变量中,您必须使用`xyz = $(echo -n $ xyz)`.此外,此方法受到可能不需要的路径名扩展(通配)的影响.

18> Luca Borrion..:

我只想使用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语法"find and replace"的说明:

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
}'



19> 小智..:
var='   a b c   '
trimmed=$(echo $var)



20> ghostdog74..:

使用AWK:

echo $var | awk '{gsub(/^ +| +$/,"")}1'


除了awk没做任何事情:回显未加引号的变量已经去除了空格

21> Nicholas Sus..:

这是一个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'


利用常规表达式的函数只处理_spaces_而不处理其他形式的空格,但很容易概括:将`if`行替换为:`[["$ trimmed"=〜[[:space:]]*([ ^ [:space:]] | [^ [:space:]].*[^ [:space:]])[[:space:]]*]]`

22> 小智..:

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

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


这不是真的.它是"回声",删除空格,而不是分配.在您的示例中,执行`echo"$ var"`以查看带空格的值.
@NicholasSushkin可以做`var = $(echo $ var)`但是我不推荐它.此处介绍的其他解决方案是首选

23> Gregor..:

这不会出现不必要的浮点问题,而且内部空白未修改(假设$IFS设置为默认值' \t\n')。

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

read -r var << eof
$var
eof



24> 小智..:

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

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

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



25> Alpesh Gediy..:

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

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

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

推荐阅读
Gbom2402851125
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有