我有一个字符串,它是我无法控制的某些操作的结果。当我使用 打印此变量时echo
,我得到:
echo $myvar
hello
然而,当我这样做时
if [ $myvar = "hello" ]; then
echo they are equal
else
echo they are not equal
fi
我总是觉得他们不平等。我怀疑这是因为newline
性格。
该字符串的行为也很奇怪。当我做:
newVAR="this is my var twice: "$myvar$myvar
echo $newVAR
我得到:
hellois my var twice: hello
我如何检查这是否确实是由 a 引起的newline
,如果是,则将其删除?
答案1
问题是您有一个嵌入式回车符(CR,\r
)。这会导致终端文本插入点返回到正在打印的行的开头。这就是为什么您在示例中的行开头看到“hello”的原因$newVAR
-sed -n l
显示不可打印字符(和行尾)的可读视图。
var=ab$'\r'c ; echo "$var"; printf %s "$var" | sed -n l
# output:
cb
ab\rc$
您可以通过简单的 bash 条件检查来测试它:
[[ $var == *$'\r'* ]] && echo yes || echo no
# output:
yes
\r
您可以通过测试(s) 并通过以下方式删除它们,将 测试和修复合并到一个步骤中:
fix="${var//$'\r'/}"; echo "$var"; echo "$fix"
# output:
cb
abc
这使固定用途外壳参数扩展。上面使用的特定形式用于根据您提供的模式替换子字符串:${parameter/pattern/string}
<-- 这仅替换第一个找到的图案和细绳在名为 *parameter 的变量中。取代全部模式,您只需将第一个更改/
为//
.
答案2
您可以\r
在$'\r'
bash 中表示:
if [ "$myvar" = "hello"$'\r' ]; then
echo they are equal
else
echo they are not equal
fi
或者将最后一个\r
切入myvar
:
if [ "${myvar%$'\r'*}" = "hello" ]; then
echo they are equal
else
echo they are not equal
fi
答案3
奇怪的是,在许多外壳中,getopts
很可能是这样的工作的候选人。乍一看,这似乎违反直觉,但如果您认为getopts
' 主要功能是识别并提供尽可能多的指定单字符命令行选项以供解释,就像在一系列相同的串联选项中可能找到的那样,它可能会开始变得有点更有意义。
为了从bash
shell 中进行演示:
x=$(printf '\n\r%010s\t' hello)
OPTIND=1
while getopts : na "-$x"
do printf %q\\n "$OPTARG"
done
$'\n'
$'\r'
\
\
\
\
\
h
e
l
l
o
$'\t'
这样,getopts
对于此类情况,有时可以方便地将拆卸处理为一种外壳自动驾驶仪。当你这样做时,你可以直接筛选出不需要的字节,case
或者[
测试]
并从字节 1 构建字符串备份:
OPTIND=1 y=$(printf \\n\\r) z=
while getopts : na "-$x"
do case $OPTARG in ([!$y])
z=$z$OPTARG
esac
done
printf %q\\n "$z"
$' hello\t'
给定这个简单的示例案例 - 并给定一个支持其他地方已经提到的参数扩展的 shell - 所述扩展可能会在这里为您提供更好的服务。但我认为getopts
如果您不知道它在这方面的功能,也可能值得一提。当然,当我了解它时,我发现了它的许多有用的应用程序。
答案4
虽然 Bash 和其他 shell 语言很方便,但有时最好使用真正的脚本语言 - 例如 Perl。 Perl 可以非常轻松地替换调用其他语言(例如 sed 和 awk)以及 UNIX 命令的 shell 脚本。 20 多年前,我在编写 C-Shell 脚本时了解到了这一点,这些脚本依次调用 sed、awk 和各种 UNIX 命令 - 然后再调用 FORTRAN 代码。在 Perl 中我会这样做:
chomp($myvar); # removes the newline char
if("$myvar" eq "hello") # string comparison
{
print "they are equal\n";
}
else
{
print "they are not equal\n";
}