I need explenation about the following behavior of arrays in shell scripting:
我需要解释一下shell脚本中数组的以下行为:
Imagine the following is given:
假设给出以下内容:
arber@host ~> ls
fileA fileB script.sh
Now i can do the following commands:
现在我可以执行以下命令:
arber@host ~> ARR=($(ls -d file*))
arber@host ~> echo ${ARR[0]} # start index 0
arber@host ~> echo ${ARR[1]} # start index 1
fileA
arber@host ~> echo ${ARR[2]} # start index 2
fileB
But when I do this via script.sh it behaves different (Start Index = 0):
但是当我通过脚本做这个的时候。sh表现不同(Start Index = 0):
arber@host ~> cat script.sh
#!/bin/bash
ARR=($(ls -d file*))
# get length of an array
aLen=${#ARR[@]}
# use for loop read all items (START INDEX 0)
for (( i=0; i<${aLen}; i++ ));
do
echo ${ARR[$i]}
done
Here the result:
这里的结果:
arber@host ~> ./script.sh
fileA
fileB
I use Ubuntu 18.04 LTS and zsh. Can someone explain this?
我使用Ubuntu 18.04 LTS和zsh。有人能解释一下这个吗?
1 个解决方案
#1
3
Arrays in Bash are indexed from zero, and in zsh they're indexed from one.
Bash中的数组从0被索引,在zsh中它们从1被索引。
But you don't need the indices for a simple use case such as this. Looping over ${array[@]}
works in both:
但是,对于这样的简单用例,不需要索引。对${array[@]}的循环作用在以下两种情况中:
files=(file*)
for f in "${files[@]}"; do
echo "$f"
done
In zsh you could also use $files
instead of "${files[@]}"
, but that doesn't work in Bash. (And there's the slight difference that it drops empty array elements, but you won't get any from file names.)
在zsh中,您也可以使用$files而不是“${files[@]}”,但这在Bash中是行不通的。(不同之处在于,它会删除空数组元素,但不会从文件名中获得任何元素。)
Also, don't use $(ls file*)
, it will break if you have filenames with spaces (see WordSpliting on BashGuide), and is completely useless to begin with.
另外,不要使用$(ls文件*),如果您有带空格的文件名(请参阅BashGuide中的WordSpliting),它将会崩溃,而且从一开始就完全没用。
The shell is perfectly capable of generating filenames by itself. That's actually what will happen there, the shell finds all files with names matching file*
, passes them to ls
, and ls
just prints them out again for the shell to read and process.
shell完全能够自己生成文件名。这就是将在那里发生的事情,shell找到所有名称匹配的文件*,将它们传递给ls, ls将它们再次打印出来,以便shell读取和处理。
#1
3
Arrays in Bash are indexed from zero, and in zsh they're indexed from one.
Bash中的数组从0被索引,在zsh中它们从1被索引。
But you don't need the indices for a simple use case such as this. Looping over ${array[@]}
works in both:
但是,对于这样的简单用例,不需要索引。对${array[@]}的循环作用在以下两种情况中:
files=(file*)
for f in "${files[@]}"; do
echo "$f"
done
In zsh you could also use $files
instead of "${files[@]}"
, but that doesn't work in Bash. (And there's the slight difference that it drops empty array elements, but you won't get any from file names.)
在zsh中,您也可以使用$files而不是“${files[@]}”,但这在Bash中是行不通的。(不同之处在于,它会删除空数组元素,但不会从文件名中获得任何元素。)
Also, don't use $(ls file*)
, it will break if you have filenames with spaces (see WordSpliting on BashGuide), and is completely useless to begin with.
另外,不要使用$(ls文件*),如果您有带空格的文件名(请参阅BashGuide中的WordSpliting),它将会崩溃,而且从一开始就完全没用。
The shell is perfectly capable of generating filenames by itself. That's actually what will happen there, the shell finds all files with names matching file*
, passes them to ls
, and ls
just prints them out again for the shell to read and process.
shell完全能够自己生成文件名。这就是将在那里发生的事情,shell找到所有名称匹配的文件*,将它们传递给ls, ls将它们再次打印出来,以便shell读取和处理。