bash scorre l'elenco delle stringhe


13

È possibile formattare questo esempio:

for i in string1 string2 stringN
do
 echo $i
done

a qualcosa di simile a questo:

for i in 
string1
string2
stringN
do
 echo $i
done

EDIT: Mi dispiace per la confusione, non ho capito che c'erano diversi metodi per eseguire lo script - sh <scriptname>contro bash <scriptname>e anche questa cosa che non posso nominare in questo momento - #!/bin/she #!/bin/bash:)


Qual è il problema che stai cercando di risolvere?
jesse_b,

Hai provato quello che stai chiedendo per vedere se avrebbe funzionato?
DopeGhoti,

@Jesse_b leggibilità e gestibilità del gruppo di stringhe

@DopeGhoti sì, l'ho fatto

@waayee: in tal caso un array è la soluzione migliore. Vedi la risposta di Glenn Jackman.
jesse_b,

Risposte:


32

L'uso di array in bash può aiutare la leggibilità: questa sintassi dell'array consente spazi bianchi arbitrari tra le parole.

strings=(
    string1
    string2
    "string with spaces"
    stringN
)
for i in "${strings[@]}"; do
    echo "$i"
done

1
Sembra molto elegante, ma sfortunatamente genera un errore: Errore di sintassi: "(" imprevisto

1
@waayee, allora non lo stai eseguendo in Bash. Ricorda che shnon è necessariamente Bash, e soprattutto non su Debian e Ubuntu.
ilkkachu,

1
@ilkkachu Penso di averlo ora - deve eseguire "bash <scriptname>" non "sh <scriptname>" :)

@waayee, oppure metti una riga hashbang / shebang corretta ed eseguila come un eseguibile. Lettura richiesta: lo shebang determina la shell che esegue lo script?
ilkkachu,

1
@rrrrr, le vostre domande sono probabilmente risposto qui: stackoverflow.com/q/12314451/7552
Glenn Jackman

4

Puoi sfuggire all'interruzione di riga con una barra rovesciata:

$ for i in \
> hello \
> world
> do
> echo $i
> done
hello
world
$

2

Puoi sfuggire alle nuove righe prima / dopo ogni elemento su cui esegui il ciclo:

for i in \
    string1 \
    string2 \
    stringN
do
   printf '%s\n' "$i"
done

Oppure, per questo semplice esempio:

printf '%s\n' string1 string2 stringN

che ha lo stesso risultato.

Relazionato:

Variazione utilizzando una bashmatrice:

strings=(
    string1
    string2
    stringN
)

printf '%s\n' "${strings[@]}"

1

Se passare a zshè un'opzione:

for string (
  string1
  'other string'
  etc..
) printf '%s\n' "$string"

0

Puoi usare il loopcomando, disponibile qui , in questo modo:

$ loop "echo $ITEM" --for string1,string2,string3

oppure, se si dispone di un elenco come file:

$ cat file_list.txt | loop "echo $ITEM"

0
list='a b c d'
for element in $list;do 
    echo "$element"
done

Ti mancano i punti e virgola!
41754

Nota che funzionerebbe fintanto che ogni stringa è una parola separata. Non appena hai spazi nelle tue stringhe, gli spazi suddividono la stringa in più parole. Inoltre, se la $liststringa contiene caratteri globbing del nome file ( list='* * * *'), la shell potrebbe sostituirli con nomi di file corrispondenti.
Kusalananda

0

Stessa cosa, meno testo:

array=(
        string{1..7}
)

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

string1ecc. non sono i valori letterali da visualizzare, sono segnaposto, quindi questo approccio non funziona.
Stephen Kitt,

in tal caso, perché preoccuparsi array ( … )? basta fare for i in string{1..7}; do echo "$i"; done; pariprintf '%s\n' string{1..7}
αғsнιη il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.