我有一个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,但我认为有一个更优雅的解决方案来解决这个问题。
当前回答
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
其他回答
你可以使用tr删除换行符:
var=`hg st -R "$path" | tr -d '\n'`
if [ -n $var ]; then
echo $var
done
# 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
让我们定义一个包含开头、结尾和中间空格的变量:
FOO=' test test test '
echo -e "FOO='${FOO}'"
# > FOO=' test test test '
echo -e "length(FOO)==${#FOO}"
# > length(FOO)==16
如何删除tr中的所有空格(由[:space:]表示):
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
如何删除前导和尾随空格-链种子:
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})"
我所知道的单行用例最简单的方法是:
echo " ABC " | sed -e 's# \+\(.\+\) \+#\1#'
工作原理:
-e启用高级正则表达式 我使用# sed,因为我不喜欢“凌乱的库”模式,如/\////\/\\\/\/ Sed希望转义大多数正则表达式控制字符,因此所有\ 否则就是^ +(.+)+$,也就是开头的空格,一组no。1,空格在最后。 所有这些都被“第一组”所取代。
因此,ABC变成了ABC。
这应该在使用sed的最新系统上得到支持。
对于标签来说,就是这样
echo " ABC " | sed -e 's#[\t ]\+\(.\+\)[\t ]\+#\1#'
对于多行内容,已经需要其他答案中描述的[:space:]这样的字符类,并且可能不是所有sed实现都支持。
参考资料:Sed手册
使用Bash的扩展模式匹配功能(shopt -s extglob),你可以这样使用:
修剪{# # * ()}
删除任意数量的前导空格。