for über eine Liste
for farbe in rot grün blau; do
echo "Farbe: $farbe"
done
for i in {1..5}; do printf "%d " "$i"; done; echo
for i in {10..0..5}; do printf "%d " "$i"; done; echo
for ((i = 0; i < 3; i++)); do echo "Zähler $i"; done # C-Stil
summe=0
for n in 1 2 3 4; do summe=$((summe + n)); done
echo "Summe: $summe"Ausgabe
Farbe: rot Farbe: grün Farbe: blau 1 2 3 4 5 10 5 0 Zähler 0 Zähler 1 Zähler 2 Summe: 10
Über Dateien
Nutze Globs, niemals for f in $(ls) (zerbricht bei Leerzeichen):
cd "$(mktemp -d)"
touch "a b.txt" c.txt d.md
for datei in *.txt; do
echo "Datei: [$datei] hat $(wc -c < "$datei") Bytes"
done
for datei in *.nix; do
[[ -e $datei ]] || { echo "keine .nix-Dateien"; break; }
doneAusgabe
Datei: [a b.txt] hat 0 Bytes Datei: [c.txt] hat 0 Bytes keine .nix-Dateien
while und until
n=3
while [[ $n -gt 0 ]]; do
echo "n=$n"
((n--))
done
i=0
until [[ $i -ge 3 ]]; do
echo "i=$i"
((i++))
doneAusgabe
n=3 n=2 n=1 i=0 i=1 i=2
Zeilen lesen
while read verarbeitet Eingaben zeilenweise. Setze IFS= und -r, damit nichts verändert wird:
printf "Mia 17\nTom 25\nZoe 31\n" | while IFS=' ' read -r name alter; do
echo "$name ist $alter"
done
while IFS=, read -r land hauptstadt; do
echo "$hauptstadt ist die Hauptstadt von $land"
done <<'DATEN'
Deutschland,Berlin
Frankreich,Paris
DATEN
mapfile -t zeilen < <(printf "eins\nzwei\ndrei\n")
echo "${#zeilen[@]} Zeilen, zweite: ${zeilen[1]}"Ausgabe
Mia ist 17 Tom ist 25 Zoe ist 31 Berlin ist die Hauptstadt von Deutschland Paris ist die Hauptstadt von Frankreich 3 Zeilen, zweite: zwei
zaehler=0
printf "a\nb\nc\n" | while read -r x; do ((zaehler++)); done
echo "mit Pipe: $zaehler"
zaehler=0
while read -r x; do ((zaehler++)); done < <(printf "a\nb\nc\n")
echo "mit Prozess-Ersetzung: $zaehler"Ausgabe
mit Pipe: 0 mit Prozess-Ersetzung: 3
break, continue, select
for i in {1..10}; do
(( i % 2 == 0 )) && continue # gerade überspringen
(( i > 7 )) && break # abbrechen
printf "%d " "$i"
done
echo
for i in 1 2; do
for j in a b c; do
[[ $j == b ]] && continue 2 # äußere Schleife fortsetzen
echo "$i$j"
done
doneAusgabe
1 3 5 7 1a 2a
Muster: Wiederholen bis es klappt
versuch=0
max=3
until (( versuch >= max )); do
((versuch++))
echo "Versuch $versuch"
if (( versuch == 2 )); then echo "geklappt"; break; fi
doneAusgabe
Versuch 1 Versuch 2 geklappt
Merke
for x in liste; do ... done, Bereiche{1..10}, C-Stil((i=0;i<n;i++))- Dateien per Glob (
*.txt), nicht per$(ls) while/untilmit Bedingung;while IFS= read -r zeile; do ... done < datei- Pipe in
whileläuft in einer Unter-Shell: Prozess-Ersetzung< <(...)nutzen breakundcontinue(auch mit Ebenenzahl)
Aufgabe
Gib alle Zahlen von 1 bis 30 aus, ersetze Vielfache von 3 durch "Fizz", von 5 durch "Buzz".