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[@]}”