如何断言字符串具有换行符,如果有,则将其删除

如何断言字符串具有换行符,如果有,则将其删除

我有一个字符串,它是我无法控制的某些操作的结果。当我使用 打印此变量时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' 主要功能是识别并提供尽可能多的指定单字符命令行选项以供解释,就像在一系列相同的串联选项中可能找到的那样,它可能会开始变得有点更有意义。

为了从bashshell 中进行演示:

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";
  }

相关内容