Sil*_*ilv 6 arrays bash shell list
我在这里搜索过类似的问题,但令人惊讶的是找不到任何问题.
在GNU bash中,有一个名为" arrays "的(一个构造?一个结构?一个数据类型?).数组在bash文档中有详细记录,所以我认为我理解了基础知识.
但突然间,在文档中也出现了"列表"一词.例如,在讨论文件名扩展时使用它(强调是我的):
如果出现其中一个字符,则该单词被视为模式,并替换为与该模式匹配的按字母顺序排列的文件名列表(请参阅模式匹配).
因此,我有三个问题:
IFS,或者与数组相同?还有另一种使用"名单"一词在谈论一个或多个管道的序列时,但我知道,很可能意味着不同类型的列表.
当"列表"优于数组时,有哪些用例?例如,让我们进行比较.让我们创建两个文件:
$ touch file1.txt file2.txt
说到列表,我可以执行以下操作:
$ A=*.txt ; echo $A
file1.txt file2.txt
$
Run Code Online (Sandbox Code Playgroud)
当涉及到数组时,我可以执行以下操作:
$ B=(*.txt) ; echo ${B[@]}
file1.txt file2.txt
$
Run Code Online (Sandbox Code Playgroud)
虽然这两个结果完全相同,但是当数组和列表返回不同的结果时是否存在任何情况?
我可能会混淆一些东西,因为在上面的例子中,它似乎是一个"包裹"在数组中的列表.我不知道它是否有所作为.
Bash中没有名为list的数据类型.我们只有数组.在您引用的文档中,术语"列表"不是指数据类型(或任何技术) - 它只是指一系列文件名.
但是,就所考虑的顺序循环而言,glob扩展的工作方式与数组元素非常相似:
for file in *.txt; do # loop through the matching files
# no need to worry about white spaces or glob characters in file names
echo "file=$file"
done
Run Code Online (Sandbox Code Playgroud)
和...一样
files=(*.txt) # put the list of matching files in an array
for file in "${files[@]}"; do # loop through the array
echo "file=$file"
done
Run Code Online (Sandbox Code Playgroud)
但是,如果您要对文件名进行硬编码,那么您需要使用引号来防止分词和通配:
for file in verycramped.txt "quite spacious.txt" "too much space.txt" "*ry nights.txt"; do ...
Run Code Online (Sandbox Code Playgroud)
要么
files=(verycramped.txt "quite spacious.txt" "too much space.txt" "*ry nights.txt")
for file in "${files[@]}"; do ...
Run Code Online (Sandbox Code Playgroud)
在这里阅读更多关于分词的内容:
术语“列表”实际上并不是 bash 中的特定技术术语;它是 bash 中的一个术语。它在语法中用于指代命令序列(例如循环体for或脚本的内容),并且这种用法已显示在程序结构的文档中,但这是非常具体的列表类型。
在您询问的上下文中,我会说“列表”是由任意数量(包括 0)的 shell单词组成的值。单个命令的参数就是这样一个列表。
\n\n反过来,shell 词可能是另一种语言中的单个字符串。通常,当您键入命令行时,它会被列出的字符$IFS(通常是空格,即空格和水平制表符)分隔成单词,但是您可以通过任何各种引用机制来避免这种情况,从而创建 shell 单词包含 IFS 字符。
如果您希望在 shell 参数中存储列表,则该参数必须是数组;在这种情况下,列表中的每个单词都会成为数组的一个元素。例如,传递到命令的参数列表在默认数组中可用,可以通过$后跟命名数组引用中方括号之间的索引来访问该数组,例如,"$@"对于返回到列表中的所有元素,"$0"对于第一个元素(即命令名称),等等。
当数组扩展回单词列表时,您有三个选择:数组的元素可以保持原样,而不管内容如何 ( "$@");它们可以通过空格连接在一起,形成一个大的单 shell 单词 ( ),或者可以首先将它们连接成一个大字符串,然后使用通常的 IFS 分隔符规则(或不使用引号)"$*"重新解析为单词。$@$*
除了一些内置函数mapfile(例如readarray)之外,bash 对数组没有太多支持。例如,环境只能包含字符串,因此不能包含export数组。尽管您当然可以使用数组(或数组切片)的值作为传递给函数的参数列表(部分或全部),但您不能将数组作为数组传递到函数中。您还可以将数组的名称传递给函数,然后该函数可以使用名称引用并eval在其调用者的范围内操作该数组,但与在任何情况下超出一个人的词法范围的所有机制一样语言,这通常被认为是不好的做法。当然,函数不能返回数组,但是 bash 函数除了一字节数字退出代码之外不能返回任何内容。它可以输出文本,但该文本是非结构化的;如果调用者通过命令或进程替换捕获它,则由调用者来解析文本,但是它需要 \xe2\x80\x93 ,例如为每一行输出创建一个包含一个元素单词的数组,即mapfile/的默认行为readarray。
无论如何,重点是,在此上下文中的列表是值,而数组是存储列表值的容器。从技术上讲,shell 参数(又名“变量”)可以是数组,并且作为数组,它们可以保存列表;它们不能是列表,并且引用“数组值”并没有真正的意义。但在非正式场合,“数组”和“列表”经常互换使用。这就是人类懒惰的本质和外壳的流动性。
\n