bash zapętla listę ciągów

15

Czy można sformatować tę próbkę:

for i in string1 string2 stringN
do
 echo $i
done

do czegoś podobnego do tego:

for i in 
string1
string2
stringN
do
 echo $i
done

EDYCJA: Przepraszam za zamieszanie, nie zdawałem sobie sprawy, że istnieją różne metody wykonywania skryptu - sh <scriptname>versus, bash <scriptname>a także to, czego nie mogę teraz wymienić - #!/bin/shi #!/bin/bash:)


źródło
Jaki problem próbujesz rozwiązać?
jesse_b
Próbowałeś tego, o co pytasz, aby sprawdzić, czy to zadziała?
DopeGhoti
1
@Jesse_b czytelność i łatwość zarządzania wiązką ciągów
@DopeGhoti tak zrobiłem
@waayee: W takim przypadku najlepszym wyborem jest tablica. Zobacz odpowiedź Glenna Jackmana.
jesse_b

Odpowiedzi:

34

Używanie tablic w bash może poprawić czytelność: ta składnia tablicy pozwala na dowolne spacje między słowami.

strings=(
    string1
    string2
    "string with spaces"
    stringN
)
for i in "${strings[@]}"; do
    echo "$i"
done
Glenn Jackman
źródło
1
Wydaje się to najbardziej eleganckie, ale niestety daje błąd: Błąd składniowy: „(„ nieoczekiwany
1
@waayee, to nie uruchamiasz go w Bash. Pamiętaj, że shniekoniecznie jest to Bash, a zwłaszcza nie dotyczy Debiana i Ubuntu.
ilkkachu
1
@ilkkachu Myślę, że dostaję to teraz - muszę uruchomić „bash <nazwa skryptu>” nie „sh <
@waayee, lub wstaw odpowiednią linię hashbang / shebang i uruchom ją jak plik wykonywalny. Wymagana lektura: Czy shebang określa powłokę uruchamiającą skrypt?
ilkkachu
1
@rrrrr, prawdopodobnie na twoje pytania można znaleźć tutaj: stackoverflow.com/q/12314451/7552
glenn jackman
4

Możesz uciec przed łamaniem linii za pomocą odwrotnego ukośnika:

$ for i in \
> hello \
> world
> do
> echo $i
> done
hello
world
$
Andy Dalton
źródło
3

Możesz uciec od nowego wiersza przed / po każdym przewijanym elemencie:

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

Lub dla tego prostego przykładu:

printf '%s\n' string1 string2 stringN

co ma ten sam wynik.

Związane z:

Odmiana za pomocą bashtablicy:

strings=(
    string1
    string2
    stringN
)

printf '%s\n' "${strings[@]}"
Kusalananda
źródło
1

Jeśli przejście do zshjest opcją:

for string (
  string1
  'other string'
  etc..
) printf '%s\n' "$string"
Stéphane Chazelas
źródło
1
list='a b c d'
for element in $list;do 
    echo "$element"
done
Gość
źródło
Brakuje średników!
41754
Zauważ, że działałoby to tak długo, jak każdy ciąg jest osobnym słowem. Gdy tylko będziesz mieć spacje w swoich ciągach, spacje podzielą ciąg na wiele słów. Ponadto, jeśli $listciąg zawiera znaki globowania nazw plików ( list='* * * *'), powłoka potencjalnie zastąpiłaby je pasującymi nazwami plików.
Kusalananda
0

Możesz użyć looppolecenia dostępnego tutaj :

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

lub, jeśli masz listę jako plik:

$ cat file_list.txt | loop "echo $ITEM"
Rich Jones
źródło
0

To samo, mniej tekstu:

array=(
        string{1..7}
)

for i in "${array[@]}"; do
    echo "$i"
done
Cornelis van Ginkel
źródło
string1itp. nie są literalnymi wartościami do wyświetlenia, są symbolami zastępczymi, więc to podejście nie działa.
Stephen Kitt
jeśli tak, to po co array ( … )? po prostu zrób for i in string{1..7}; do echo "$i"; done; parzystyprintf '%s\n' string{1..7}
αғsнιη