【发布时间】:2018-11-21 16:05:59
【问题描述】:
如何在 unix shell 脚本中创建数组?
【问题讨论】:
如何在 unix shell 脚本中创建数组?
【问题讨论】:
以下代码在 shell 中创建并打印一个字符串数组:
#!/bin/bash
array=("A" "B" "ElementC" "ElementE")
for element in "${array[@]}"
do
echo "$element"
done
echo
echo "Number of elements: ${#array[@]}"
echo
echo "${array[@]}"
结果:
A
B
ElementC
ElementE
Number of elements: 4
A B ElementC ElementE
【讨论】:
在 bash 中,你可以像这样创建数组
arr=(one two three)
调用元素
$ echo "${arr[0]}"
one
$ echo "${arr[2]}"
three
要询问用户输入,您可以使用 read
read -p "Enter your choice: " choice
【讨论】:
/bin/sh,引发错误line 1: syntax error: unexpected "("。你知道替代方案吗?
Bourne shell 不支持数组。但是,有两种方法可以处理此问题。
使用位置 shell 参数 $1、$2 等:
$ set one two three
$ echo $*
one two three
$ echo $#
3
$ echo $2
two
使用变量评估:
$ n=1 ; eval a$n="one"
$ n=2 ; eval a$n="two"
$ n=3 ; eval a$n="three"
$ n=2
$ eval echo \$a$n
two
【讨论】:
bash(虽然它可以从端口安装)。假设bash 功能编写的脚本不可移植,而且它们明显慢于大多数 Bourne shell 实现(如dash,这在 GNU/Linux 发行版中很常见)。 bash 是一个不错的交互式 shell,但编写脚本很慢。
$* 被认为是有害的。通常,$@ 是首选,因为它的作用相同,但会保留空格。 $@ 扩展为 "$1" "$2" "$3" ... "$n",而 $* 扩展为 "$1x$2x$3x...$n",其中 x 为 @ 987654332@ 分隔符(很可能是空格)。
$@ 与$* 相同;差异仅在引用时显示:"$*" 是一个单词,而 "$@" 保留原始单词中断。
bash,因此针对 bash 的响应是合适的,但确实不应该假设 /bin/sh 是 bash。
#!/bin/bash
# define a array, space to separate every item
foo=(foo1 foo2)
# access
echo "${foo[1]}"
# add or changes
foo[0]=bar
foo[2]=cat
foo[1000]=also_OK
您可以阅读 ABS 《高级 Bash 脚本指南》
【讨论】:
/bin/sh,引发错误line 1: syntax error: unexpected "("。你知道替代方案吗?
Bourne shell 和 C shell 没有数组,IIRC。
除了别人说的,在Bash中你可以得到数组中的元素个数如下:
elements=${#arrayname[@]}
并进行切片式操作:
arrayname=(apple banana cherry)
echo ${arrayname[@]:1} # yields "banana cherry"
echo ${arrayname[@]: -1} # yields "cherry"
echo ${arrayname[${#arrayname[@]}-1]} # yields "cherry"
echo ${arrayname[@]:0:2} # yields "apple banana"
echo ${arrayname[@]:1:1} # yields "banana"
【讨论】:
set 命令(set name=(wordlist))和“变量替换”部分($name[selector] 和 @ 987654327@)。据我所知,csh 一直支持数组。例如,请参见 $path 数组变量,它反映了 $PATH 环境变量。
试试这个:
echo "Find the Largest Number and Smallest Number of a given number"
echo "---------------------------------------------------------------------------------"
echo "Enter the number"
read n
i=0
while [ $n -gt 0 ] #For Seperating digits and Stored into array "x"
do
x[$i]=`expr $n % 10`
n=`expr $n / 10`
i=`expr $i + 1`
done
echo "Array values ${x[@]}" # For displaying array elements
len=${#x[*]} # it returns the array length
for (( i=0; i<len; i++ )) # For Sorting array elements using Bubble sort
do
for (( j=i+1; j<len; j++ ))
do
if [ `echo "${x[$i]} > ${x[$j]}"|bc` ]
then
t=${x[$i]}
t=${x[$i]}
x[$i]=${x[$j]}
x[$j]=$t
fi
done
done
echo "Array values ${x[*]}" # Displaying of Sorted Array
for (( i=len-1; i>=0; i-- )) # Form largest number
do
a=`echo $a \* 10 + ${x[$i]}|bc`
done
echo "Largest Number is : $a"
l=$a #Largest number
s=0
while [ $a -gt 0 ] # Reversing of number, We get Smallest number
do
r=`expr $a % 10`
s=`echo "$s * 10 + $r"|bc`
a=`expr $a / 10`
done
echo "Smallest Number is : $s" #Smallest Number
echo "Difference between Largest number and Smallest number"
echo "=========================================="
Diff=`expr $l - $s`
echo "Result is : $Diff"
echo "If you try it, We can get it"
【讨论】:
您的问题涉及“unix shell 脚本”,但标记为bash。这是两个不同的答案。
shell 的 POSIX 规范对数组没有任何规定,因为最初的 Bourne shell 不支持它们。即使在今天,在 FreeBSD、Ubuntu Linux 和许多其他系统上,/bin/sh 也不支持阵列。因此,如果您希望您的脚本在不同的 Bourne 兼容 shell 中工作,则不应使用它们。或者,如果您假设一个特定的外壳,那么请确保将其全名放在 shebang 行中,例如#!/usr/bin/env bash.
如果您使用的是bash 或zsh,或者ksh 的现代版本,您可以像这样创建一个数组:
myArray=(first "second element" 3rd)
并访问这样的元素
$ echo "${myArray[1]}" # for bash/ksh; for zsh, echo $myArray[2]
second element
您可以通过"${myArray[@]}" 获取所有元素。您可以使用切片符号 ${array[@]:start:length} 来限制引用的数组部分,例如"${myArray[@]:1}" 省略第一个元素。
数组的长度是${#myArray[@]}。您可以使用"${!myArray[@]}" 从现有数组中获取包含所有索引的新数组。
ksh93 之前的旧版本 ksh 也有数组,但没有基于括号的表示法,也不支持切片。不过,您可以像这样创建一个数组:
set -A myArray -- first "second element" 3rd
【讨论】:
您可以尝试以下类型:
#!/bin/bash
declare -a arr
i=0
j=0
for dir in $(find /home/rmajeti/programs -type d)
do
arr[i]=$dir
i=$((i+1))
done
while [ $j -lt $i ]
do
echo ${arr[$j]}
j=$((j+1))
done
【讨论】:
数组可以通过两种方式加载。
set -A TEST_ARRAY alpha beta gamma
或
X=0 # Initialize counter to zero.
-- 使用字符串 alpha、beta 和 gamma 加载数组
for ELEMENT in alpha gamma beta
do
TEST_ARRAY[$X]=$ELEMENT
((X = X + 1))
done
另外,我认为以下信息可能会有所帮助:
shell 支持一维数组。最大数组数 元素为 1,024。定义数组时,它会自动 尺寸为 1,024 个元素。一维数组包含一个 数组元素的序列,就像连接的棚车 一起在火车轨道上。
如果你想访问数组:
echo ${MY_ARRAY[2] # Show the third array element
gamma
echo ${MY_ARRAY[*] # Show all array elements
- alpha beta gamma
echo ${MY_ARRAY[@] # Show all array elements
- alpha beta gamma
echo ${#MY_ARRAY[*]} # Show the total number of array elements
- 3
echo ${#MY_ARRAY[@]} # Show the total number of array elements
- 3
echo ${MY_ARRAY} # Show array element 0 (the first element)
- alpha
【讨论】:
如果您想要一个支持空格的键值存储,请使用-A 参数:
declare -A programCollection
programCollection["xwininfo"]="to aquire information about the target window."
for program in ${!programCollection[@]}
do
echo "The program ${program} is used ${programCollection[${program}]}"
done
http://linux.die.net/man/1/bash "关联数组是使用 declare -A name 创建的。"
【讨论】:
有多种方法可以在 shell 中创建数组。
ARR[0]="ABC"
ARR[1]="BCD"
echo ${ARR[*]}
${ARR[*]} 打印数组中的所有元素。
第二种方法是:
ARR=("A" "B" "C" "D" 5 7 "J")
echo ${#ARR[@]}
echo ${ARR[0]}
${#ARR[@]}用于计算数组的长度。
【讨论】:
从键盘读取值并将元素插入数组
# enter 0 when exit the insert element
echo "Enter the numbers"
read n
while [ $n -ne 0 ]
do
x[$i]=`expr $n`
read n
let i++
done
#display the all array elements
echo "Array values ${x[@]}"
echo "Array values ${x[*]}"
# To find the array length
length=${#x[*]}
echo $length
【讨论】:
arr=("sharlock" "bomkesh" "feluda" ) ##declare array
len=${#arr[*]} #determine length of array
# iterate with for loop
for (( i=0; i<len; i++ ))
do
echo ${arr[$i]}
done
【讨论】:
在 ksh 中你这样做:
set -A array element1 element2 elementn
# view the first element
echo ${array[0]}
# Amount elements (You have to substitute 1)
echo ${#array[*]}
# show last element
echo ${array[ $(( ${#array[*]} - 1 )) ]}
【讨论】:
echo "${array[@]:(-1)}"。这样就不需要写两次数组变量名了。