2009-12-10 2 views
56

Как создать массив в сценариях unix shell?Массивы в оболочке unix?

+0

Первый вопрос - отличный вопрос, но что с ним связано? – Frank

+1

http://www.gnu.org/software/bash/manual/html_node/Arrays.html –

+0

См. [Массивы в Unix Bourne Shell] (http://unix.stackexchange.com/questions/137566/arrays-in -unix-bourne-shell # 137571) – agc

ответ

3

Вы можете попробовать следующий тип:

#!/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 
+0

разбивает имена каталогов на пробелы. используйте цикл чтения IFS, чтобы позаботиться об этом. – ghostdog74

9
#!/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 "Advanced Bash-Scripting Guide"

44

в Баш, вы создаете массив, как это

arr=(one two three) 

для вызова элементов

$ echo ${arr[0]} 
one 
$ echo ${arr[2]} 
three 

попросить пользовательского ввода, вы можете использовать функцию чтения

read -p "Enter your choice: " choice 

является то, что вы просите.?

5

Корпус Bourne и оболочка C не имеют массивов, 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" 
+0

csh имеет массивы. –

+0

@KeithThompson: он не задокументирован на [man page] (http://linux.die.net/man/1/csh), но функциональность действительно присутствует, по крайней мере, в некоторых версиях. –

+2

В man-странице не упоминаются «массивы» с помощью этого имени, но смотрите документацию команды 'set' (' set name = (wordlist) ') и раздел« Variable substituion »(' $ name [selector] ' и '$ {name [селектор]}'). Насколько я знаю, csh всегда поддерживал массивы. См., Например, переменную массива '$ path', которая отражает переменную среды $ PATH. –

0

В 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)) ]} 
+0

Более кратким способом отображения последнего элемента является 'echo '$ {array [@]: (- 1)}" '. Это устраняет необходимость записи имени переменной массива дважды. –

5

Попробуйте это:

echo "Find the Largest Number and Smallest Number of a given number" 
echo "---------------------------------------------------------------------------------" 
echo "Enter the number" 
read n 

while [ $n -gt 0 ] #For Seperating digits and Stored into array "x" 
do 
     x[$i]=`expr $n % 10` 
     n=`expr $n/10` 
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" 
12

Bourne 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 
+1

Bash поддерживает массивы. Не уверен в оригинальной оболочке Bourne, но bash более распространен в наши дни ... – plesiv

+2

@zplesivcak - ... на GNU/Linux, так как это предмет GNU. Например, * FreeBSD * не поставляется с 'bash' (он доступен для установки из портов). Сценарии, написанные с использованием функций 'bash', не являются переносимыми, и они заметно медленнее, чем большинство реализаций оболочки Bourne (например,' dash', который * является общим в дистрибутивах GNU/Linux). 'bash' - это приятная интерактивная оболочка, но для сценариев она медленная. – tjameson

+1

'$ *' считается вредным. Как правило, '$ @' является предпочтительным, поскольку он делает то же самое, но сохраняет пробелы. '$ @' расширяется как «$ 1» «$ 2» «$ 3» ... «$ n», а '$ *' расширяется как «$ 1x $ 2x $ 3x ... $ n», где 'x' это разделитель '$ IFS' (скорее всего, пробел). – zserge

1

считывать значения из клавиатуры и вставка элемента в массив

# 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 
56

Следующий код создает и печатает массив строк в оболочке:

#!/bin/bash 
array=("A" "B" "ElementC" "ElementE") 
for element in ${array[@]} 
do 
    echo $element 
done 

echo "" 
echo "Nbr of elements:" ${#array[@]} 

echo "" 
echo ${array[@]} 

Результат:

A 
B 
ElementC 
ElementE 

Nbr of elements: 4 

A B ElementC ElementE 
+9

Вы уверены, что это работает с '#!/Bin/sh' shebang? Думаю, вам нужно использовать '#!/Bin/bash', чтобы использовать это. – timurb

+0

Спасибо Erthad. Действительно, я изменил его на #!/Bin/bash. –

3

Если вы хотите хранилище ключей значение с поддержкой пространств использовать -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 «Ассоциативные массивы создаются с помощью объявить -A имя. "

4

Массив можно загрузить в двух направлениях.

set -A TEST_ARRAY alpha beta gamma 

или

X=0 # Initialize counter to zero. 

- Загрузить массив с альфа строк, бета- и гамма-

for ELEMENT in alpha gamma beta 
do 
    TEST_ARRAY[$X]=$ELEMENT 
    ((X = X + 1)) 
done 

Кроме того, я думаю, что ниже информация может помочь:

Оболочка поддерживает одномерные массивы. Максимальное количество элементов массива составляет 1,024. Когда массив определен, он автоматически имеет размер 1024 элемента. Одномерный массив содержит последовательность элементов массива , которые похожи на боксеры, соединенные вместе на дорожке поезда.

В случае, если вы хотите получить доступ к массиву:

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 
3

Ваш вопрос спрашивает о "Unix сценариев оболочки", но помечен bash. Это два разных ответа.

Спецификация POSIX для оболочек не имеет права говорить о массивах, поскольку оригинальная оболочка Bourne не поддерживала их. Даже сегодня, на FreeBSD, Ubuntu Linux и многих других системах, /bin/sh не поддерживает массив. Поэтому, если вы хотите, чтобы ваш скрипт работал в разных совместимых с Bourne оболочках, вы не должны их использовать. В качестве альтернативы, если вы принимаете определенную оболочку, то обязательно укажите ее полное имя в строке shebang, например. #!/usr/bin/env bash.

Если вы используете bash или zsh или современную версию ksh, вы можете создать массив так:

myArray=(first "second element" 3rd) 

и доступ к элементам как этот

$ echo "${myArray[1]}" 
second element 

Вы можете получить все элементы через "${myArray[@]}". Вы можете использовать ноту среза $ {array [@]: start: length}, чтобы ограничить часть массива, на который ссылаются, например. "${myArray[@]:1}", чтобы опустить первый элемент.

Длина массива ${#myArray[@]}. Вы можете получить новый массив, содержащий все индексы из существующего массива с "${!myArray[@]}".

Старые версии ksh до ksh93 также имели массивы, но не обозначали скобки и не поддерживали нарезку. Вы можете создать такой массив, как это:

set -A myArray -- first "second element" 3rd 
Смежные вопросы