我有一个shell脚本与这段代码:
var=`hg st -R "$path"`
if [ -n "$var" ]; then
echo $var
fi
但是条件代码总是执行,因为hg st总是打印至少一个换行符。
是否有一个简单的方法从$var中剥离空白(如PHP中的trim())?
or
有没有处理这个问题的标准方法?
我可以使用sed或AWK,但我认为有一个更优雅的解决方案来解决这个问题。
我有一个shell脚本与这段代码:
var=`hg st -R "$path"`
if [ -n "$var" ]; then
echo $var
fi
但是条件代码总是执行,因为hg st总是打印至少一个换行符。
是否有一个简单的方法从$var中剥离空白(如PHP中的trim())?
or
有没有处理这个问题的标准方法?
我可以使用sed或AWK,但我认为有一个更优雅的解决方案来解决这个问题。
当前回答
这里有一个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'
其他回答
剥离一个前导和一个后导空间
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'
# 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
有一个解决方案只使用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一起工作。
参考
从Bash变量中删除前导和尾随空格(原始源代码)
Use:
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"
}
它适用于各种空格,包括换行符, 不需要修改shop。 它保留内部空白,包括换行符。
单元测试(用于手动检查):
#!/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
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