ubuntuusers.de

Für diese Funktion musst du eingeloggt sein.

Schleife und Array

Status: Gelöst | Ubuntu-Version: Kein Ubuntu
Antworten |

Zottel83

Anmeldungsdatum:
9. Februar 2015

Beiträge: 115

Hallo, ich bin gerade dabei ein Bash Skript zu schreiben. In diesem Skript habe ich ein Array erstellt und der Inhalt des Arrays wird Zeilenweise in eine Datei geschrieben. Dazu verwende ich eine For Do Schleife:

for i in $(seq 1 $max)
do

echo ${array[$i]} >> $zielpfad

done

$(seq 1 $max) wird verwendet um der Schleife zu sagen wie groß das Array ist. Soweit so gut. Jetzt aber zu dem Problem: Es kommt nämlich auch mal vor, dass im Array ein bestimmtes Zeichen gefunden wird, was zur Folge hat, dass diese und die nächsten 3 Zeilen nicht in die Zieldatei eingetragen werden sollen, bzw ausgelassen werden müssen. Das sieht dann in etwa so aus:

if [[ ${Array[$i]} == *"/"* ]]; then
 i=$(($i + 3))
fi

Hier soll wenn ein Backslash gefunden wird diese und die nächsten 3 Zeilen nicht geschrieben zu werden und ich habe halt versucht, den Zähler der For-Do Schleife um 3 zu erhöhen, aber das funktioniert so leider nicht, es wird trotzdem beim direkt nächsten Array-Eintrag weiter gemacht. Weiß jemand, wie ich das Problem lösen kann?

frostschutz

Avatar von frostschutz

Anmeldungsdatum:
18. November 2010

Beiträge: 7791

klassische schleife mit zähler

1
2
3
4
5
6
for ((i=0; i<$max; i++))
do
    # mach was mit "${Array[$i]}" oder auch nicht

    # hier kann jetzt i auch verändert werden
done

wenn es kein array wäre sondern eine parameterliste

1
2
3
4
5
6
7
8
# z.B. set -- "${Array[@]}"

for $var in "$@"
do
    # mach was mit "$1"

    shift # oder shift 3 oder ...
done

Bearbeitet von rklm:

Syntaxhighlighting

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13219

frostschutz schrieb:

wenn es kein array wäre sondern eine parameterliste

Die ist ebenfalls ein Array!

1
2
3
4
5
6
7
8
# z.B. set -- "${Array[@]}"

for $var in "$@"
do
    # mach was mit "$1"

    shift # oder shift 3 oder ...
done

shift ergibt keinen Sinn, wenn man so (mit for ... in) über ein Array iteriert, denn es wird das zu iterierende Objekt während des Durchlaufs verändert. So etwas ist oft eine Quelle von undefiniertem oder überraschendem Verhalten. In meinen Tests hatte der shift einfach keine Wirkung. Das ist auch logisch, denn im Kopf der for-Schleife wird der Wert des Arrays bereits ein mal expandiert (also kopiert) und der shift wirkt nur auf das Original.

Eine Lösung ist:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
array=(foo '*/*' bar baz abc boz)
i=0
limit=${#array[@]}

while [ $i -lt $limit ]; do
  e="${array[i]}"
  echo "$e"
  
  if  [ -z "${e##*/*}" ]; then
    i=$((i + 4))
  else
    i=$((i + 1))
  fi
done

In der bash kann man auch die schon erwähnte for-Schleife nutzen:

1
2
3
4
5
6
7
8
for ((i=0; i < $limit; ++i)); do
  e="${array[i]}"
  echo "$e"
  
  if  [ -z "${e##*/*}" ]; then
    i=$((i + 3))
  fi
done

Edit: Bedingung für die Erkennung vom "/" korrigiert.

frostschutz

Avatar von frostschutz

Anmeldungsdatum:
18. November 2010

Beiträge: 7791

Ja, sorry. War spät gestern 😀 muss man while [ $# -gt 0 ] oder wie auch immer.

Ich bin oft in einer busybox Shell unterwegs... da hast du das klassische Array nicht und so kommt man dann auf Tricks mit der set shift.

Zottel83

(Themenstarter)

Anmeldungsdatum:
9. Februar 2015

Beiträge: 115

Vielen lieben Dank euch beiden, das hat mir geholfen. Ich komme immernoch nicht mit der Syntax der For-Do Schleife klar. Ich kenne sie ja aus BlitzBasic und Autoit und dort sind sie etwas einfacher aufgebaut.

Btw: Warum wurde mein Thema beim Erstellen zunächst als Spam erkannt, der erst von einem Mod überprüft werden musste?

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13219

Zottel83 schrieb:

Vielen lieben Dank euch beiden, das hat mir geholfen.

Bitte!

Btw: Warum wurde mein Thema beim Erstellen zunächst als Spam erkannt, der erst von einem Mod überprüft werden musste?

Kann ich im Detail nicht sagen. Das kommt ab und an mal vor.

Antworten |