String 我如何知道在Bash中字符串只包含一个或多个单词?

String 我如何知道在Bash中字符串只包含一个或多个单词?,string,bash,String,Bash,当我获取字符串中数组的内容时,我有以下两种解决方案: $ a=('one' 'two') $ str1="${a[*]}" && str2="${a[@]}" 当然,之后,我可以在代码上重用我的字符串 但是我怎么知道我的变量只有一个或几个字呢?在这两种情况下,数组的内容都连接到一个字符串并分配给变量。唯一的区别是用于连接元素的内容。对于${a[*]},将使用IFS的第一个字符。在${a[@]}中,始终使用单个空格 $ a=(one two) $ IFS="-" $ str1="

当我获取字符串中数组的内容时,我有以下两种解决方案:

$ a=('one' 'two')
$ str1="${a[*]}" && str2="${a[@]}"
当然,之后,我可以在代码上重用我的字符串
但是我怎么知道我的变量只有一个或几个字呢?

在这两种情况下,数组的内容都连接到一个字符串并分配给变量。唯一的区别是用于连接元素的内容。对于
${a[*]}
,将使用
IFS
的第一个字符。在
${a[@]}
中,始终使用单个空格

$ a=(one two)
$ IFS="-"
$ str1="${a[*]}"
$ str2="${a[@]}"
$ echo "$str1"
one-two
$ echo "$str2"
one two

当展开
$str1
$str2
而不加引号时,结果字数完全取决于
IFS
的当前值,而不管变量最初是如何定义的
“$str1”
“$str2”
当然,每一个词都可以扩展成一个单词。

为了补充@chepner的伟大答案:
${arr[*]}
${arr[@]}
之间的区别与
$*
$$
之间的区别非常相似。你可能想参考这篇文章,它讨论了
$*
$@

根据经验,使用
“$@”
“${arr[@]}”
总是比它们的非引号或
*
对应项更好。

“${a[*]}”
将所有条目一起扩展为一个字符串,而
“${a[@]}”将每个条目扩展为一个字符串

假设我们有一个程序
printParameters
,它为每个参数(
$1
$2
,等等)打印字符串
my。。。参数为…

>_ a=('one' 'two')

>_ printParameters "${a[*]}"
my 1. parameter is one two

>_ printParameters "${a[@]}"
my 1. parameter is one
my 2. parameter is two
如果要手动展开数组,则需要写入
${a[*]}
作为
的“一二”

${a[@]}
作为
一个“两个”

IFS
等方面也存在差异(参见其他答案)。通常,
@
是更好的选择,但
*
要快得多–在需要处理大型数组且不需要单独参数的情况下,使用后一种方法

顺便说一下:脚本
printParameters
可以写成

#! /bin/bash
argIndex=0
for argValue in "$@"; do
    echo "my $((++i)). argument is $argValue"
done

这对于通过尝试和错误学习更多关于扩展的知识非常有用

我不会说使用
@
更好,而是更可能的是
@
做了您想要做的事情。一个重要的区别(尽管我认为它在最近的Bash版本中已经修复):
“$@”
在没有参数的情况下扩展为零,而
“${arr[@]}
在数组为空的情况下会导致错误。这太烦人了。。。你必须使用
${arr[@]+“${arr[@]}”
来获得相同的结果(例如,对于
循环,通常在
中很有用)。@Fred对于
foo
“${foo[@]}”似乎无法重现任何错误,至少在
bash
3.2或4.4中是如此。这是早期4.x版本中的回归吗?@chepner抱歉,我忘了提到这是使用
set-u
。我在我所有的脚本中都系统地使用它,所以对我来说,
set-u
所做的就是我的“心理默认”
“$@”
即使在
set-u
下没有位置参数的情况下也不会出错。最起码的研究会发现很多。当我写这篇文章时,标题并不是真正的标题:“Bash中${array[]}和${array[@]}之间的差异?”。对我来说,${array[]}和${array[@]}之间没有混淆。有人更改了我的标题,但她没有阅读我的问题,即“我如何知道我的变量只有一个或几个单词?”您的问题是关于使用
[*]
[@]
进行数组扩展的问题。链接的问题解释了差异——如果您想知道数组元素的数量,请使用
${a[@]}
。如果您想在扩展后计算扩展数组中的单词数,我想最简单的方法是将其转换回数组并计算元素数<代码>s=“${a[@]}”;b=($s);回音“${b[@]}”