Arrays in Unix-Shell?

Antworten:

89

Der folgende Code erstellt und druckt ein Array von Zeichenfolgen in der 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[@]}"

Ergebnis:

A
B
ElementC
ElementE

Number of elements: 4

A B ElementC ElementE
Vincent Agami
quelle
61

In Bash erstellen Sie ein Array wie dieses

arr=(one two three)

die Elemente aufrufen

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

Um nach Benutzereingaben zu fragen, können Sie read verwenden

read -p "Enter your choice: " choice
Ghostdog74
quelle
Die durch Leerzeichen getrennte Deklaration funktioniert NICHT mit dem /bin/shAuslösen eines Fehlers line 1: syntax error: unexpected "(". Kennen Sie eine Alternative?
Mhyousefi
20

Die Bourne-Shell unterstützt keine Arrays. Es gibt jedoch zwei Möglichkeiten, um das Problem zu lösen.

Verwenden Sie die Positionsschalenparameter $ 1, $ 2 usw.:

$ set one two three
$ echo $*
one two three
$ echo $#
3
$ echo $2
two

Verwenden Sie variable Auswertungen:

$ 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
Mischka
quelle
1
Bash unterstützt Arrays. Ich
bin
2
@zplesivcak - ... unter GNU / Linux, da es eine GNU-Sache ist. Zum Beispiel wird FreeBSD nicht mitgeliefert bash(es kann jedoch über Ports installiert werden). Geschriebene Skripte vorausgesetzt bashFunktionen sind nicht tragbar, und sie sind merklich langsamer langsamer als die meisten Bourne - Shell - Implementierungen (wie dash, das ist auf GNU / Linux - Distributionen üblich). bashist eine schöne interaktive Shell, aber für die Skripterstellung ist sie langsam.
Beatgammit
1
$*gilt als schädlich. Normalerweise wird $@es bevorzugt, da es dasselbe tut, aber Leerzeichen behält. $@wird als "$ 1" "2 $" , "$ 3" ... "$ n" erweitert, während $*als "$ $ 1x 2x 3x $ ... $ n" erweitert wird, wo xist $IFSSeparator (am wahrscheinlichsten, Raum).
Zserge
1
Nicht zitiert, $@ist das gleiche wie $*; Der Unterschied zeigt sich nur in Anführungszeichen: "$*"ist ein Wort, während "$@"die ursprünglichen Wortumbrüche erhalten bleiben.
Mark Reed
Die Frage ist markiert bash, daher sind bash-spezifische Antworten angemessen, aber es ist sicher richtig, dass man nicht davon ausgehen sollte, dass /bin/shes sich um bash handelt.
Mark Reed
13
#!/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

Sie können das ABS "Advanced Bash-Scripting Guide" lesen.

Lai Jiangshan
quelle
3
Bitte überdenken Sie das Vorschlagen des ABS als Lernressource - es ist in vielerlei Hinsicht eine Möglichkeit, W3Schools in HTML und Javascript zu verprügeln. Es enthält viel Google-Saft, zeigt jedoch in vielen Beispielen schlechte Praktiken und wird selten und unzureichend aktualisiert. Das Wiki der Bash-Hacker ist eine viel bessere Ressource. So ist der BashGuide .
Charles Duffy
Die durch Leerzeichen getrennte Deklaration funktioniert NICHT mit dem /bin/shAuslösen eines Fehlers line 1: syntax error: unexpected "(". Kennen Sie eine Alternative?
Mhyousefi
8

Die Bourne-Shell und die C-Shell haben keine Arrays, IIRC.

Zusätzlich zu den Aussagen anderer können Sie in Bash die Anzahl der Elemente in einem Array wie folgt abrufen:

elements=${#arrayname[@]}

und führen Sie Operationen im Slice-Stil aus:

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"
Bis auf weiteres angehalten.
quelle
csh hat Arrays.
Keith Thompson
@KeithThompson: Es ist nicht in der Manpage dokumentiert, aber die Funktionalität scheint zumindest in einigen Versionen vorhanden zu sein.
Bis auf weiteres angehalten.
3
In der Manpage werden "Arrays" mit diesem Namen nicht erwähnt, es wird jedoch auf die Dokumentation des setBefehls ( set name=(wordlist)) und den Abschnitt "Variablensubstitution" ( $name[selector]und ${name[selector]}) verwiesen . Soweit ich weiß, hat csh immer Arrays unterstützt. Siehe zum Beispiel die $pathArray-Variable, die die $PATHUmgebungsvariable widerspiegelt.
Keith Thompson
8

Versuche dies :

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"
muthukrishnavinayagam
quelle
Das funktioniert nur in ksh und bash, oder?
Lassi
6

Ihre Frage fragt nach "Unix Shell Scripting", ist aber markiert bash. Das sind zwei verschiedene Antworten.

Die POSIX-Spezifikation für Shells hat nichts zu Arrays zu sagen, da die ursprüngliche Bourne-Shell sie nicht unterstützte. Unter FreeBSD bietet Ubuntu Linux und viele andere Systeme /bin/shauch heute noch keine Array-Unterstützung. Wenn Sie also möchten, dass Ihr Skript in verschiedenen Bourne-kompatiblen Shells funktioniert, sollten Sie sie nicht verwenden. Wenn Sie alternativ eine bestimmte Shell annehmen, müssen Sie den vollständigen Namen in die Shebang-Zeile einfügen, z #!/usr/bin/env bash.

Wenn Sie bash oder zsh oder eine moderne Version von ksh verwenden , können Sie ein Array wie das folgende erstellen:

myArray=(first "second element" 3rd)

und auf solche Elemente zugreifen

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

Sie können alle Elemente über erhalten "${myArray[@]}". Sie können die Slice-Notation $ {array [@]: start: length} verwenden , um den Teil des referenzierten Arrays einzuschränken, z. B. "${myArray[@]:1}"um das erste Element wegzulassen.

Die Länge des Arrays beträgt ${#myArray[@]}. Sie können ein neues Array mit allen Indizes aus einem vorhandenen Array mit erhalten "${!myArray[@]}".

Ältere Versionen von ksh vor ksh93 hatten ebenfalls Arrays, aber weder die auf Klammern basierende Notation, noch unterstützten sie das Schneiden. Sie können jedoch ein Array wie das folgende erstellen:

set -A myArray -- first "second element" 3rd 
Mark Reed
quelle
5

Sie können den folgenden Typ ausprobieren:

#!/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
Roopesh Majeti
quelle
Unterbricht Verzeichnisnamen mit Leerzeichen. Verwenden Sie dazu eine while-Leseschleife von IFS.
Ghostdog74
5

Ein Array kann in zwei Richtungen geladen werden.

set -A TEST_ARRAY alpha beta gamma

oder

X=0 # Initialize counter to zero.

- Laden Sie das Array mit den Zeichenfolgen Alpha, Beta und Gamma

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

Ich denke auch, dass die folgenden Informationen hilfreich sein können:

Die Shell unterstützt eindimensionale Arrays. Die maximale Anzahl von Array-Elementen beträgt 1.024. Wenn ein Array definiert wird, wird es automatisch auf 1.024 Elemente dimensioniert. Ein eindimensionales Array enthält eine Folge von Array-Elementen, die den auf einer Bahnstrecke miteinander verbundenen Güterwagen ähneln.

Falls Sie auf das Array zugreifen möchten:

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
Pinaki Mukherjee
quelle
4

Wenn Sie einen Schlüsselwertspeicher mit Unterstützung für Leerzeichen möchten, verwenden Sie den -AParameter:

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 "Assoziative Arrays werden mit deklarieren -A-Namen erstellt."

richardjsimkins
quelle
4

Es gibt mehrere Möglichkeiten, ein Array in der Shell zu erstellen.

ARR[0]="ABC"
ARR[1]="BCD"
echo ${ARR[*]}

${ARR[*]} druckt alle Elemente im Array.

Der zweite Weg ist:

ARR=("A" "B" "C" "D" 5 7 "J")
echo ${#ARR[@]}
echo ${ARR[0]}

${#ARR[@]} wird verwendet, um die Länge des Arrays zu zählen.

Manjotsingh Chug
quelle
Schöne Antwort: Toller Start für einen Neuling. Und willkommen zu Upvote Levels ;-)
GhostCat
3

Lesen Sie die Werte aus dem Keybord und fügen Sie das Element in das Array ein

# 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
Abs
quelle
1

In ksh machst du es:

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 )) ]}
user224243
quelle
Eine präzisere Möglichkeit, das letzte Element anzuzeigen, ist echo "${array[@]:(-1)}". Dadurch entfällt die Notwendigkeit, den Namen der Arrayvariablen zweimal zu schreiben.
Alex Dupuy
1

Ein einfacher Weg:

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
Hautausschläge
quelle