我有一个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,但我认为有一个更优雅的解决方案来解决这个问题。
当前回答
答案有很多,但我仍然认为我刚刚写的剧本值得一提,因为:
it was successfully tested in the shells bash/dash/busybox shell it is extremely small it doesn't depend on external commands and doesn't need to fork (->fast and low resource usage) it works as expected: it strips all spaces and tabs from beginning and end, but not more important: it doesn't remove anything from the middle of the string (many other answers do), even newlines will remain special: the "$*" joins multiple arguments using one space. if you want to trim & output only the first argument, use "$1" instead if doesn't have any problems with matching file name patterns etc
脚本:
trim() {
local s2 s="$*"
until s2="${s#[[:space:]]}"; [ "$s2" = "$s" ]; do s="$s2"; done
until s2="${s%[[:space:]]}"; [ "$s2" = "$s" ]; do s="$s2"; done
echo "$s"
}
用法:
mystring=" here is
something "
mystring=$(trim "$mystring")
echo ">$mystring<"
输出:
>here is
something<
其他回答
你可以使用tr删除换行符:
var=`hg st -R "$path" | tr -d '\n'`
if [ -n $var ]; then
echo $var
done
赋值函数忽略前导和后面的空格,因此可以用于修剪:
$ var=`echo ' hello'`; echo $var
hello
从Bash指南的通配符部分
在参数展开中使用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";
如果我们将函数更改为在subshell中执行,我们不必担心检查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
将空格移到一个空格:
(text) | fmt -su
让我们定义一个包含开头、结尾和中间空格的变量:
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})"