string 如何从 Bash 变量中修剪空格?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/369758/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to trim whitespace from a Bash variable?
提问by too much php
I have a shell script with this code:
我有一个带有此代码的shell脚本:
var=`hg st -R "$path"`
if [ -n "$var" ]; then
echo $var
fi
But the conditional code always executes, because hg st
always prints at least one newline character.
但是条件代码总是会执行,因为hg st
总是至少打印一个换行符。
- Is there a simple way to strip whitespace from
$var
(liketrim()
in PHP)?
- 有没有一种简单的方法来去除空格
$var
(比如trim()
在PHP 中)?
or
或者
- Is there a standard way of dealing with this issue?
- 有没有标准的方法来处理这个问题?
I could use sedor AWK, but I'd like to think there is a more elegant solution to this problem.
回答by MattyV
Let's define a variable containing leading, trailing, and intermediate whitespace:
让我们定义一个包含前导、尾随和中间空格的变量:
FOO=' test test test '
echo -e "FOO='${FOO}'"
# > FOO=' test test test '
echo -e "length(FOO)==${#FOO}"
# > length(FOO)==16
How to remove all whitespace (denoted by [:space:]
in tr
):
如何删除所有空格(用[: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
How to remove leading whitespace only:
如何仅删除前导空格:
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
How to remove trailing whitespace only:
如何仅删除尾随空格:
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
How to remove both leading and trailing spaces--chain the sed
s:
如何删除前导和尾随空格 - 链接sed
s:
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
Alternatively, if your bash supports it, you can replace echo -e "${FOO}" | sed ...
with sed ... <<<${FOO}
, like so (for trailing whitespace):
或者,如果您的 bash 支持它,您可以替换echo -e "${FOO}" | sed ...
为sed ... <<<${FOO}
,像这样(用于尾随空格):
FOO_NO_TRAIL_SPACE="$(sed -e 's/[[:space:]]*$//' <<<${FOO})"
回答by makevoid
A simple answer is:
一个简单的答案是:
echo " lol " | xargs
Xargswill do the trimming for you. It's one command/program, no parameters, returns the trimmed string, easy as that!
Xargs将为您进行修剪。这是一个命令/程序,没有参数,返回修剪后的字符串,就这么简单!
Note: this doesn't remove all internal spaces so "foo bar"
stays the same; it does NOT become "foobar"
. However, multiple spaces will be condensed to single spaces, so "foo bar"
will become "foo bar"
. In addition it doesn't remove end of lines characters.
注意:这不会删除所有内部空间,因此"foo bar"
保持不变;它不会变成"foobar"
. 但是,多个空格会被压缩为单个空格,因此"foo bar"
会变成"foo bar"
. 此外,它不会删除行尾字符。
回答by bashfu
There is a solution which only uses Bash built-ins called wildcards:
有一个只使用 Bash 内置插件的解决方案,称为通配符:
var=" abc "
# remove leading whitespace characters
var="${var#"${var%%[![:space:]]*}"}"
# remove trailing whitespace characters
var="${var%"${var##*[![:space:]]}"}"
printf '%s' "===$var==="
Here's the same wrapped in a function:
这是封装在函数中的相同内容:
trim() {
local var="$*"
# remove leading whitespace characters
var="${var#"${var%%[![:space:]]*}"}"
# remove trailing whitespace characters
var="${var%"${var##*[![:space:]]}"}"
printf '%s' "$var"
}
You pass the string to be trimmed in quoted form. e.g.:
您以引号形式传递要修剪的字符串。例如:
trim " abc "
A nice thing about this solution is that it will work with any POSIX-compliant shell.
这个解决方案的一个好处是它可以与任何符合 POSIX 的 shell 一起工作。
Reference
参考
回答by bashfu
Bash has a feature called parameter expansion, which, among other things, allows string replacement based on so-called patterns(patterns resemble regular expressions, but there are fundamental differences and limitations). [flussence's original line: Bash has regular expressions, but they're well-hidden:]
Bash 有一个称为参数扩展的特性,除其他外,它允许基于所谓的模式(模式类似于正则表达式,但存在根本差异和限制)的字符串替换。[flussence 的原话:Bash 有正则表达式,但它们隐藏得很好:]
The following demonstrates how to remove allwhite space (even from the interior) from a variable value.
下面演示了如何从变量值中删除所有空白(甚至从内部)。
$ 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
回答by rkachach
In order to remove all the spaces from the beginning and the end of a string (including end of line characters):
为了删除字符串开头和结尾的所有空格(包括行尾字符):
echo $variable | xargs echo -n
This will remove duplicate spaces also:
这也将删除重复的空格:
echo " this string has a lot of spaces " | xargs echo -n
Produces: 'this string has a lot of spaces'
产生:'这个字符串有很多空格'
回答by Brian Cain
Strip one leading and one trailing space
去掉一个前导和一个尾随空格
trim()
{
local trimmed=""
# Strip leading space.
trimmed="${trimmed## }"
# Strip trailing space.
trimmed="${trimmed%% }"
echo "$trimmed"
}
For example:
例如:
test1="$(trim " one leading")"
test2="$(trim "one trailing ")"
test3="$(trim " one leading and one trailing ")"
echo "'$test1', '$test2', '$test3'"
Output:
输出:
'one leading', 'one trailing', 'one leading and one trailing'
Strip allleading and trailing spaces
去除所有前导和尾随空格
trim()
{
local trimmed=""
# Strip leading spaces.
while [[ $trimmed == ' '* ]]; do
trimmed="${trimmed## }"
done
# Strip trailing spaces.
while [[ $trimmed == *' ' ]]; do
trimmed="${trimmed%% }"
done
echo "$trimmed"
}
For example:
例如:
test4="$(trim " two leading")"
test5="$(trim "two trailing ")"
test6="$(trim " two leading and two trailing ")"
echo "'$test4', '$test5', '$test6'"
Output:
输出:
'two leading', 'two trailing', 'two leading and two trailing'
回答by GuruM
From Bash Guide section on globbing
来自 Bash 指南关于globbing 的部分
To use an extglob in a parameter expansion
在参数扩展中使用 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
Here's the same functionality wrapped in a function (NOTE: Need to quote input string passed to function):
这是封装在函数中的相同功能(注意:需要引用传递给函数的输入字符串):
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=
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.
}
Usage:
用法:
string=" abc def ghi ";
#need to quote input-string to preserve internal white-space if any
trimmed=$(trim "$string");
echo "$trimmed";
If we alter the function to execute in a subshell, we don't have to worry about examining the current shell option for extglob, we can just set it without affecting the current shell. This simplifies the function tremendously. I also update the positional parameters "in place" so I don't even need a local variable
如果我们将函数更改为在子 shell 中执行,我们不必担心检查 extglob 的当前 shell 选项,我们可以设置它而不影响当前 shell。这极大地简化了功能。我还“就地”更新了位置参数,所以我什至不需要局部变量
trim() {
shopt -s extglob
set -- "${1##+([[:space:]])}"
printf "%s" "${1%%+([[:space:]])}"
}
so:
所以:
$ 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
回答by VAmp
You can trim simply with echo
:
你可以简单地修剪echo
:
foo=" qsdqsd qsdqs q qs "
# Not trimmed
echo \'$foo\'
# Trim
foo=`echo $foo`
# Trimmed
echo \'$foo\'
回答by Paul Tomblin
I've always done it with sed
我一直都是用 sed 做的
var=`hg st -R "$path" | sed -e 's/ *$//'`
If there is a more elegant solution, I hope somebody posts it.
如果有更优雅的解决方案,我希望有人发布它。
回答by Adam Rosenfield
You can delete newlines with tr
:
您可以使用以下命令删除换行符tr
:
var=`hg st -R "$path" | tr -d '\n'`
if [ -n $var ]; then
echo $var
done