【问题标题】:Bash not recognising strings as equalBash 不认为字符串是相等的
【发布时间】:2015-03-28 00:50:20
【问题描述】:

我有两个变量linesorted,它们都是以空格分隔的数字字符串。我的部分脚本取决于检查这两个字符串是否相等:

if [[ $sorted == $line ]]
then
echo "test"
fi

运行它时,我没有得到任何输出。目视检查,使用:echo $sortedecho $line 给出两个看似相似的输出。

我认为这可能是由于两个输出中的任何一个在末尾都有一个额外的空格字符,所以我决定检查从字符串中删除空格是否可以解决问题:

test1=`echo $sorted | tr -d ' '`
test2=`echo $line | tr -d ' '`

后续执行:

if [[ "$test1" == "$test2" ]]
then 
echo "test"
fi

确实提供了所需的“测试”输出。但是,当使用wc 比较两个变量的字符数时,两个变量的输出是相同的。此外,用echo <variable> | grep -o "\s" | wc -l also 检查linesorted 中空白字符的数量,这两个变量的输出相同。

我的问题是什么可能导致这种行为;运行tr 可以解决问题,但是用wcgrep 计算空格的数量表明空格(或至少是字符)的数量是相似的。

【问题讨论】:

  • 尝试使用 $sorted -eq $line ?
  • @doc -eq 用于比较整数,而不是字符串。
  • 如果不引用变量,您的grep/wc 计数测试几乎肯定是不正确的。 wc -l 计算行数,而您的 echo 输出应该只有一行(如果您不引用变量,即使变量内容是空格分隔而不是换行分隔)。
  • 实际上,您甚至应该将if [[ $sorted == $line ]] 中的变量用双引号引起来——如果没有引号,$line 将被视为模式(即受通配符匹配)而不是纯字符串。试试[[ [a-z] == [a-z] ]] && echo match[[ abcd == a* ]] && echo match 看看这个效果。

标签: bash if-statement


【解决方案1】:

我认为您用于查看字符串是否相同的某些测试已损坏,因为您没有引用变量。此测试应显示两个变量的不同计数:

echo "$var_name" | grep -c "\s"

您可以使用declare -p var_name 查看变量的内容,它应该会显示前导/尾随空格的位置。

当您使用 bash 时,您还可以利用 <<< here string 语法,而不是使用 echo

grep -c "\s" <<<"$var_name"

正如kojiro 在 cmets 中指出的那样(感谢),这是一种更强大的方法,并且可以节省创建子外壳的时间。

【讨论】:

  • 与其使用echo,不如考虑使用grep -c "\s" &lt;&lt;&lt; "$var_name"。管道不仅创建了一个子shell,而且这里的字符串不受某些可能破坏echo的格式(例如前导破折号)的影响。
  • @kojiro 已编辑,谢谢。我知道&lt;&lt;&lt; 是内置的,但您能否详细说明echo 和格式的问题?
  • echo 支持一些选项:-n-e-E。因此,传递未经处理的参数可能会导致意想不到的效果。仔细引用可以避免其中一些影响,但即便如此,最好还是了解它们。例如:x=(-n hello world); echo "${x[@]}"
  • ...bash 的回声特别支持这些选项;另一方面,POSIX echo 支持这些选项,而 bash 通过包含它们实际上打破了 POSIX sh 标准。 (这就是为什么使用printf 而不是echo 通常是一种好的做法的部分原因)。
猜你喜欢
  • 1970-01-01
  • 2013-06-06
  • 2011-03-17
  • 1970-01-01
  • 2012-08-19
  • 2022-07-07
  • 2015-09-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多