arrays - uguale - script bash operatori




Passare attraverso una serie di stringhe in Bash? (13)

Array implicito per script o funzioni:

Oltre alla risposta corretta di anubhava : Se la sintassi di base per il ciclo è:

for item ;do
    echo "This is item: $item."
  done

c'è un caso speciale in bash :

Quando si esegue uno script o una funzione, gli argomenti passati alle righe di comando verranno assegnati alla variabile [email protected] array, è possibile accedere da $1 , $2 , $3 e così via.

Questo può essere popolato (per test) da

set -- arg1 arg2 arg3 ...
for item ;do
    echo "This is item: $item."
  done
This is item: arg1.
This is item: arg2.
This is item: arg3.
This is item: ....

Un loop su questo array potrebbe essere scritto semplicemente:

for item in "[email protected]";do
    echo "This is item: $item."
  done

Si noti che il lavoro riservato non è presente e nemmeno il nome dell'array!

Campione:

#!/bin/bash

for item ;do
    printf "Doing something with '%s'.\n" "$item"
  done

Si noti che questo è lo stesso di

./myscript.sh arg1 arg2 arg3 ...
Doing something with 'arg1'.
Doing something with 'arg2'.
Doing something with 'arg3'.
Doing something with '...'.

Quindi in una sceneggiatura :

myfunc() { for item;do cat <<<"Working about '$item'."; done ; }

Salva questo in uno script myscript.sh , chmod +x myscript.sh , quindi

myfunc item1 tiem2 time3
Working about 'item1'.
Working about 'tiem2'.
Working about 'time3'.

Lo stesso in una funzione :

arr=(foo bar baz)

for i in ${!arr[@]}
do
    echo $i "${arr[i]}"
done

Poi

0 foo
1 bar
2 baz

Voglio scrivere uno script che attraversa 15 stringhe (array possibilmente?) È possibile?

Qualcosa di simile a:

for databaseName in listOfNames
then
  # Do something
end

È simile alla risposta dell'utente2533809, ma ogni file verrà eseguito come comando separato.

#!/bin/bash
names="RA
RB
R C
RD"

while read -r line; do
    echo line: "$line"
done <<< "$names"

Eseguo un ciclo attraverso una serie di miei progetti per un aggiornamento git pull :

#!/bin/sh
projects="
web
ios
android
"
for project in $projects do
    cd  $HOME/develop/$project && git pull
end

L'array dichiarare non funziona per la shell di Korn. Usa l'esempio seguente per la shell Korn:

set -- arg1 arg2 arg3 ...

Modo semplice:

arr=("sharlock"  "bomkesh"  "feluda" )  ##declare array

len=${#arr[*]}  # it returns the array length

#iterate with while loop
i=0
while [ $i -lt $len ]
do
    echo ${arr[$i]}
    i=$((i+1))
done


#iterate with for loop
for i in $arr
do
  echo $i
done

#iterate with splice
 echo ${arr[@]:0:3}

Nello stesso spirito della risposta di 4ndrew:

listOfNames="RA
RB
R C
RD"

# To allow for other whitespace in the string:
# 1. add double quotes around the list variable, or
# 2. see the IFS note (under 'Side Notes')

for databaseName in "$listOfNames"   #  <-- Note: Added "" quotes.
do
  echo "$databaseName"  # (i.e. do action / processing of $databaseName here...)
done

# Outputs
# RA
# RB
# R C
# RD

B. Nessuno spazio bianco nei nomi:

listOfNames="RA
RB
R C
RD"

for databaseName in $listOfNames  # Note: No quotes
do
  echo "$databaseName"  # (i.e. do action / processing of $databaseName here...)
done

# Outputs
# RA
# RB
# R
# C
# RD

Gli appunti

  1. Nel secondo esempio, usando listOfNames="RA RB RC RD" ha lo stesso risultato.

Altri modi per inserire dati includono:

  • stdin (elencato sotto),
  • variables ,
  • una matrice (la risposta accettata),
  • un file ...

Leggi da stdin

# line delimited (each databaseName is stored on a line)
while read databaseName
do
  echo "$databaseName"  # i.e. do action / processing of $databaseName here...
done # <<< or_another_input_method_here
  1. il delimitatore IFS "field separator to line" [ 1 ] può essere specificato nello script per consentire altri spazi bianchi (es. IFS='\n' , o per MacOS IFS='\r' )
  2. Mi piace anche la risposta accettata :) - Ho incluso questi frammenti come altri modi utili che rispondono anche alla domanda.
  3. Compreso #!/bin/bash nella parte superiore del file di script indica l'ambiente di esecuzione.
  4. Mi ci sono voluti mesi per capire come codificare questo semplicemente :)

Altre fonti ( mentre il ciclo di lettura )


Possibile prima riga di ogni script / sessione Bash:

say() { for line in "${@}" ; do printf "%s\n" "${line}" ; done ; }

Utilizzare ad esempio:

$ aa=( 7 -4 -e ) ; say "${aa[@]}"
7
-4
-e

Può prendere in considerazione: echo interpreta -e come opzione qui


Prova questo. Funziona e testato.

for k in "${array[@]}"
do
    echo $k
done

# For accessing with the echo command: echo ${array[0]}, ${array[1]}

Puoi utilizzare la sintassi di ${arrayName[@]}

List=$(cat List_entries.txt)
echo $List
echo '$List'
echo "$List"
echo ${List[*]}
echo '${List[*]}'
echo "${List[*]}"
echo ${List[@]}
echo '${List[@]}'
echo "${List[@]}"

Questa è la soluzione più semplice, assumendo che non ci siano spazi nei nomi:

listOfNames="db_one db_two db_three"
for databaseName in $listOfNames
do
  echo $databaseName
done

Se usi la shell Korn, c'è " set -A databaseName ", altrimenti c'è " declare -a databaseName "

Per scrivere uno script che funzioni su tutte le shell,

 set -A databaseName=("db1" "db2" ....) ||
        declare -a databaseName=("db1" "db2" ....)
# now loop 
for dbname in "${arr[@]}"
do
   echo "$dbname"  # or whatever

done

Dovrebbe funzionare su tutte le shell.


Sorpreso che nessuno ha ancora pubblicato questo post - se hai bisogno degli indici degli elementi mentre stai scorrendo l'array, puoi fare questo:

promote_sla_chk_lst="cdi xlob"

set -A promote_arry $promote_sla_chk_lst

for i in ${promote_arry[*]};
    do
            echo $i
    done

Produzione:

for var in "${arr[@]}" ;do ...$var... ;done

Lo trovo molto più elegante rispetto allo stile "tradizionale" per il ciclo ( for (( i=0; i<${#arr[@]}; i++ )) ).

( ${!arr[@]} e $i non ho bisogno di essere citato perché sono solo numeri, alcuni suggerirebbero di citarli comunque, ma questa è solo una preferenza personale.)


for databaseName in db_one db_two db_three
do
  echo $databaseName
done

o semplicemente

listofNames = "A B C D"

for databaseName in $listOfNames; do
    echo $databaseName
done




unix