too*_*php 854 string variables bash trim
我有一个包含以下代码的shell脚本:
var=`hg st -R "$path"`
if [ -n "$var" ]; then
echo $var
fi
Run Code Online (Sandbox Code Playgroud)
但条件代码总是执行,因为hg st始终打印至少一个换行符.
$var(比如trim()在PHP中)?要么
小智 976
让我们定义一个包含前导,尾随和中间空格的变量:
FOO=' test test test '
echo -e "FOO='${FOO}'"
# > FOO=' test test test '
echo -e "length(FOO)==${#FOO}"
# > length(FOO)==16
Run Code Online (Sandbox Code Playgroud)
如何删除所有空格(用[: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
Run Code Online (Sandbox Code Playgroud)
如何仅删除前导空格:
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
Run Code Online (Sandbox Code Playgroud)
如何仅删除尾随空格:
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
Run Code Online (Sandbox Code Playgroud)
如何删除前导和尾随空格 - 链接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
Run Code Online (Sandbox Code Playgroud)
或者,如果您的bash支持它,您可以替换echo -e "${FOO}" | sed ...为sed ... <<<${FOO},如此(对于尾随空格):
FOO_NO_TRAIL_SPACE="$(sed -e 's/[[:space:]]*$//' <<<${FOO})"
Run Code Online (Sandbox Code Playgroud)
mak*_*oid 881
一个简单的答案是:
echo " lol " | xargs
Run Code Online (Sandbox Code Playgroud)
Xargs会为你做修剪.它是一个命令/程序,没有参数,返回修剪过的字符串,就这么简单!
注意:这不会删除内部空间,因此"foo bar"保持不变.它不会成为"foobar".
小智 322
有一个解决方案只使用称为通配符的 Bash内置函数:
var=" abc "
# remove leading whitespace characters
var="${var#"${var%%[![:space:]]*}"}"
# remove trailing whitespace characters
var="${var%"${var##*[![:space:]]}"}"
echo "===$var==="
Run Code Online (Sandbox Code Playgroud)
这里包含在函数中:
trim() {
local var="$*"
# remove leading whitespace characters
var="${var#"${var%%[![:space:]]*}"}"
# remove trailing whitespace characters
var="${var%"${var##*[![:space:]]}"}"
echo -n "$var"
}
Run Code Online (Sandbox Code Playgroud)
您以引用的形式传递要剪裁的字符串.例如:
trim " abc "
Run Code Online (Sandbox Code Playgroud)
这个解决方案的一个好处是它可以与任何符合POSIX的shell一起使用.
小智 76
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
Run Code Online (Sandbox Code Playgroud)
rka*_*ach 56
为了从字符串的开头和结尾删除所有空格(包括行尾字符):
echo $variable | xargs echo -n
Run Code Online (Sandbox Code Playgroud)
这将删除重复的空格:
echo " this string has a lot of spaces " | xargs echo -n
Run Code Online (Sandbox Code Playgroud)
产生:'这个字符串有很多空格'
小智 50
trim()
{
local trimmed="$1"
# Strip leading space.
trimmed="${trimmed## }"
# Strip trailing space.
trimmed="${trimmed%% }"
echo "$trimmed"
}
Run Code Online (Sandbox Code Playgroud)
例如:
test1="$(trim " one leading")"
test2="$(trim "one trailing ")"
test3="$(trim " one leading and one trailing ")"
echo "'$test1', '$test2', '$test3'"
Run Code Online (Sandbox Code Playgroud)
输出:
'one leading', 'one trailing', 'one leading and one trailing'
Run Code Online (Sandbox Code Playgroud)
trim()
{
local trimmed="$1"
# Strip leading spaces.
while [[ $trimmed == ' '* ]]; do
trimmed="${trimmed## }"
done
# Strip trailing spaces.
while [[ $trimmed == *' ' ]]; do
trimmed="${trimmed%% }"
done
echo "$trimmed"
}
Run Code Online (Sandbox Code Playgroud)
例如:
test4="$(trim " two leading")"
test5="$(trim "two trailing ")"
test6="$(trim " two leading and two trailing ")"
echo "'$test4', '$test5', '$test6'"
Run Code Online (Sandbox Code Playgroud)
输出:
'two leading', 'two trailing', 'two leading and two trailing'
Run Code Online (Sandbox Code Playgroud)
Gur*_*ruM 38
从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
Run Code Online (Sandbox Code Playgroud)
这是函数中包含的相同功能(注意:需要引用传递给函数的输入字符串):
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.
}
Run Code Online (Sandbox Code Playgroud)
用法:
string=" abc def ghi ";
#need to quote input-string to preserve internal white-space if any
trimmed=$(trim "$string");
echo "$trimmed";
Run Code Online (Sandbox Code Playgroud)
如果我们改变要在子shell中执行的函数,我们不必担心检查extglob的当前shell选项,我们可以设置它而不影响当前的shell.这极大地简化了功能.我还"就地"更新位置参数,所以我甚至不需要局部变量
trim() {
shopt -s extglob
set -- "${1##+([[:space:]])}"
printf "%s" "${1%%+([[:space:]])}"
}
Run Code Online (Sandbox Code Playgroud)
所以:
$ 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
Run Code Online (Sandbox Code Playgroud)
小智 38
你可以简单地修剪echo:
foo=" qsdqsd qsdqs q qs "
# Not trimmed
echo \'$foo\'
# Trim
foo=`echo $foo`
# Trimmed
echo \'$foo\'
Run Code Online (Sandbox Code Playgroud)
Moo*_*shu 24
使用Bash的扩展模式匹配功能enabled(shopt -s extglob),您可以使用:
{trimmed##*( )}
删除任意数量的前导空格.
Pau*_*lin 23
我总是用sed完成它
var=`hg st -R "$path" | sed -e 's/ *$//'`
Run Code Online (Sandbox Code Playgroud)
如果有一个更优雅的解决方案,我希望有人发布它.
Ada*_*eld 21
您可以删除换行符tr:
var=`hg st -R "$path" | tr -d '\n'`
if [ -n $var ]; then
echo $var
done
Run Code Online (Sandbox Code Playgroud)
fla*_*let 18
# 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
Run Code Online (Sandbox Code Playgroud)
Mos*_*itz 14
这就是我所做的,并且完美而简单:
the_string=" test"
the_string=`echo $the_string`
echo "$the_string"
Run Code Online (Sandbox Code Playgroud)
输出:
test
Run Code Online (Sandbox Code Playgroud)
Ada*_*son 12
纯粹在 BASH 中有一些不同的选项:
line=${line##+([[:space:]])} # strip leading whitespace; no quote expansion!
line=${line%%+([[:space:]])} # strip trailing whitespace; no quote expansion!
line=${line//[[:space:]]/} # strip all whitespace
line=${line//[[:space:]]/} # strip all whitespace
line=${line//[[:blank:]]/} # strip all blank space
Run Code Online (Sandbox Code Playgroud)
前两者需要extglob预先设置/启用:
shopt -s extglob # bash only
Run Code Online (Sandbox Code Playgroud)
注意:引号内的变量扩展破坏了上面的两个示例!
POSIX 括号表达式的模式匹配行为详细信息请参见此处。如果您使用的是更现代/可破解的 shell,例如 Fish,则有用于字符串修剪的内置函数。
gMa*_*ale 11
这对我有用:
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>
Run Code Online (Sandbox Code Playgroud)
为了相同的结果,将它放在更少的行上:
text=" trim my edges "
trimmed=${${text##+( )}%%+( )}
Run Code Online (Sandbox Code Playgroud)
Dan*_*der 11
有很多答案,但我仍然相信我刚写的脚本值得一提,因为:
"$*"使用一个空格连接多个参数.如果要仅修剪和输出第一个参数,请"$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"
}
Run Code Online (Sandbox Code Playgroud)
用法:
mystring=" here is
something "
mystring=$(trim "$mystring")
echo ">$mystring<"
Run Code Online (Sandbox Code Playgroud)
输出:
>here is
something<
Run Code Online (Sandbox Code Playgroud)
poj*_*ojo 10
你可以使用老派tr.例如,这将返回git存储库中已修改文件的数量,并删除空白.
MYVAR=`git ls-files -m|wc -l|tr -d ' '`
Run Code Online (Sandbox Code Playgroud)
NOY*_*OYB 10
# Strip leading and trailing white space (new line inclusive).
trim(){
[[ "$1" =~ [^[:space:]](.*[^[:space:]])? ]]
printf "%s" "$BASH_REMATCH"
}
Run Code Online (Sandbox Code Playgroud)
要么
# 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")")"
}
Run Code Online (Sandbox Code Playgroud)
要么
# 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]}"
}
Run Code Online (Sandbox Code Playgroud)
要么
# 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")"
}
Run Code Online (Sandbox Code Playgroud)
要么
建立在moskit的expr soulution上......
# Strip leading and trailing white space (new line inclusive).
trim(){
printf "%s" "`expr "$1" : "^[[:space:]]*\(.*[^[:space:]]\)[[:space:]]*$"`"
}
Run Code Online (Sandbox Code Playgroud)
要么
# 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")")"
}
Run Code Online (Sandbox Code Playgroud)
我见过脚本只是使用变量赋值来完成这项工作:
$ xyz=`echo -e 'foo \n bar'`
$ echo $xyz
foo bar
Run Code Online (Sandbox Code Playgroud)
空白会自动合并和修剪.必须注意shell元字符(潜在的注入风险).
我还建议在shell条件中始终双引变量替换:
if [ -n "$var" ]; then
Run Code Online (Sandbox Code Playgroud)
因为变量中的-o或其他内容可能会修改您的测试参数.
我只想使用sed:
function trim
{
echo "$1" | sed -n '1h;1!H;${;g;s/^[ \t]*//g;s/[ \t]*$//g;p;}'
}
Run Code Online (Sandbox Code Playgroud)
a)单行字符串的使用示例
string=' wordA wordB wordC wordD '
trimmed=$( trim "$string" )
echo "GIVEN STRING: |$string|"
echo "TRIMMED STRING: |$trimmed|"
Run Code Online (Sandbox Code Playgroud)
输出:
GIVEN STRING: | wordA wordB wordC wordD |
TRIMMED STRING: |wordA wordB wordC wordD|
Run Code Online (Sandbox Code Playgroud)
b)多行字符串的使用示例
string=' wordA
>wordB<
wordC '
trimmed=$( trim "$string" )
echo -e "GIVEN STRING: |$string|\n"
echo "TRIMMED STRING: |$trimmed|"
Run Code Online (Sandbox Code Playgroud)
输出:
GIVEN STRING: | wordAA
>wordB<
wordC |
TRIMMED STRING: |wordAA
>wordB<
wordC|
Run Code Online (Sandbox Code Playgroud)
c)最后注意事项:
如果您不喜欢使用函数,对于单行字符串,您只需使用"更容易记住"命令,例如:
echo "$string" | sed -e 's/^[ \t]*//' | sed -e 's/[ \t]*$//'
Run Code Online (Sandbox Code Playgroud)
例:
echo " wordA wordB wordC " | sed -e 's/^[ \t]*//' | sed -e 's/[ \t]*$//'
Run Code Online (Sandbox Code Playgroud)
输出:
wordA wordB wordC
Run Code Online (Sandbox Code Playgroud)
使用上面的多行字符串也可以使用,但请注意它也会删除任何尾随/前导内部多个空格,正如GuruM在评论中注意到的那样
string=' wordAA
>four spaces before<
>one space before< '
echo "$string" | sed -e 's/^[ \t]*//' | sed -e 's/[ \t]*$//'
Run Code Online (Sandbox Code Playgroud)
输出:
wordAA
>four spaces before<
>one space before<
Run Code Online (Sandbox Code Playgroud)
因此,如果你想留意这些空间,请使用我的答案开头的功能!
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
}'
Run Code Online (Sandbox Code Playgroud)
使用AWK:
echo $var | awk '{gsub(/^ +| +$/,"")}1'
Run Code Online (Sandbox Code Playgroud)
这是一个trim()函数,用于修剪和标准化空格
#!/bin/bash
function trim {
echo $*
}
echo "'$(trim " one two three ")'"
# 'one two three'
Run Code Online (Sandbox Code Playgroud)
另一个使用正则表达式的变体.
#!/bin/bash
function trim {
local trimmed="$@"
if [[ "$trimmed" =~ " *([^ ].*[^ ]) *" ]]
then
trimmed=${BASH_REMATCH[1]}
fi
echo "$trimmed"
}
echo "'$(trim " one two three ")'"
# 'one two three'
Run Code Online (Sandbox Code Playgroud)
小智 6
这是我见过的最简单的方法。它只使用 Bash,只有几行,正则表达式很简单,它匹配所有形式的空格:
if [[ "$test" =~ ^[[:space:]]*([^[:space:]].*[^[:space:]])[[:space:]]*$ ]]
then
test=${BASH_REMATCH[1]}
fi
Run Code Online (Sandbox Code Playgroud)
这是一个用于测试它的示例脚本:
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."
Run Code Online (Sandbox Code Playgroud)
小智 6
一个简单的答案是:
sed 's/^\s*\|\s*$//g'
Run Code Online (Sandbox Code Playgroud)
一个例子:
$ before=$( echo -e " \t a b \t ")
$ echo "(${before})"
( a b )
$ after=$( echo "${before}" | sed 's/^\s*\|\s*$//g' )
$ echo "(${after})"
(a b)
Run Code Online (Sandbox Code Playgroud)
小智 5
赋值忽略前导和尾随空格,因此可用于修剪:
$ var=`echo ' hello'`; echo $var
hello
Run Code Online (Sandbox Code Playgroud)
这不会出现不必要的浮点问题,而且内部空白未修改(假设$IFS设置为默认值' \t\n')。
它读取直到第一个换行符(并且不包括它)或字符串的末尾(以先到者为准),并去除前导和尾随空格和\t字符的任何混合。如果要保留多行(并去除开头和结尾的换行符),请read -r -d '' var << eof改用;但是请注意,如果您输入的内容恰好包含\neof,它将在之前被截断。(即使将其他形式的空白,即\r,\f和\v,也不会删除,即使将它们添加到$ IFS中也是如此。)
read -r var << eof
$var
eof
Run Code Online (Sandbox Code Playgroud)
小智 5
要从左至第一个单词删除空格和制表符,请输入:
echo " This is a test" | sed "s/^[ \t]*//"
Run Code Online (Sandbox Code Playgroud)
cyberciti.biz/tips/delete-leading-spaces-from-front-of-each-word.html
这将从字符串中删除所有空格,
VAR2="${VAR2//[[:space:]]/}"
Run Code Online (Sandbox Code Playgroud)
/替换//字符串中第一次出现的空格和所有出现的空格。即所有空白都被替换为–什么都没有
| 归档时间: |
|
| 查看次数: |
1238087 次 |
| 最近记录: |