GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Wie schreibe ich eine Schleife in Bash?

Ein häufiger Grund, warum Menschen die Unix-Shell lernen möchten, ist die Erschließung der Leistungsfähigkeit der Stapelverarbeitung. Wenn Sie eine Reihe von Aktionen für viele Dateien ausführen möchten, besteht eine Möglichkeit darin, einen Befehl zu erstellen, der diese Dateien durchläuft. In der Programmierterminologie wird dies als Ausführungssteuerung, bezeichnet und eines der häufigsten Beispiele dafür ist for Schleife.

Ein für Schleife ist ein Rezept, das genau beschreibt, welche Aktionen Ihr Computer für ausführen soll jedes Datenobjekt (z. B. eine Datei), das Sie angeben.

Die klassische for-Schleife

Das Linux-Terminal

  • Die 7 besten Terminalemulatoren für Linux
  • 10 Befehlszeilentools für die Datenanalyse unter Linux
  • Jetzt herunterladen:SSH-Spickzettel
  • Spickzettel für fortgeschrittene Linux-Befehle
  • Linux-Befehlszeilen-Tutorials

Eine einfach auszuprobierende Schleife ist eine, die eine Sammlung von Dateien analysiert. Dies ist wahrscheinlich keine nützliche Schleife für sich allein, aber es ist ein sicherer Weg, um sich selbst zu beweisen, dass Sie die Fähigkeit haben, jede Datei in einem Verzeichnis einzeln zu handhaben. Erstellen Sie zunächst eine einfache Testumgebung, indem Sie ein Verzeichnis erstellen und einige Kopien einiger Dateien darin ablegen. Anfangs ist jede Datei geeignet, spätere Beispiele erfordern jedoch Grafikdateien (wie JPEG, PNG oder ähnliches). Sie können den Ordner mit einem Dateimanager oder im Terminal erstellen und Dateien hineinkopieren:

$ mkdir example
        $ cp ~/Pictures/vacation/*.{png,jpg} example

Wechseln Sie in Ihr neues Verzeichnis und listen Sie dann die darin enthaltenen Dateien auf, um zu bestätigen, dass Ihre Testumgebung Ihren Erwartungen entspricht:

$ cd example
$ ls -1
cat.jpg
design_maori.png
otago.jpg
waterfall.png

Die Syntax, um jede Datei einzeln in einer Schleife zu durchlaufen, lautet:Erstellen Sie eine Variable (f für Datei, zum Beispiel). Definieren Sie dann den Datensatz, den die Variable durchlaufen soll. Gehen Sie in diesem Fall mit * durch alle Dateien im aktuellen Verzeichnis Platzhalterzeichen (das * Wildcard stimmt mit alles überein ). Beenden Sie diesen einleitenden Satz dann mit einem Semikolon (; ).

$ for f in * ; 

Je nach Vorliebe können Sie Return drücken hier. Die Shell wird nicht versuchen, die Schleife auszuführen, bis sie syntaktisch vollständig ist.

Definieren Sie als Nächstes, was bei jeder Iteration der Schleife passieren soll. Verwenden Sie der Einfachheit halber die Datei Befehl, um ein paar Daten über jede Datei zu erhalten, dargestellt durch das f Variable (aber mit vorangestelltem $). um der Shell mitzuteilen, dass sie den Wert der Variablen gegen den aktuellen Inhalt der Variable austauschen soll):

do file $f ; 

Schließen Sie die Klausel mit einem weiteren Semikolon ab und schließen Sie die Schleife:

done 

Drücken Sie Zurück um die Shell zu starten, die alles durchläuft im aktuellen Verzeichnis. Das für Schleife weist jede Datei einzeln der Variablen f zu und führt Ihren Befehl aus:

$ für f in *; do
       > Datei $f;
       > done
        cat.jpg:JPEG-Bilddaten, EXIF-Standard 2.2
        design_maori.png:PNG-Bilddaten, 4608 x 2592, 8-Bit /color RGB, non-interlaced
        otago.jpg:JPEG-Bilddaten, EXIF-Standard 2.2
       waterfall.png:PNG-Bilddaten, 4608 x 2592, 8-Bit/Farb-RGB, non-interlaced

Sie können es auch so schreiben:

$ für f in *; Datei $f ausführen; done
        cat.jpg:JPEG-Bilddaten, EXIF-Standard 2.2
        design_maori.png:PNG-Bilddaten, 4608 x 2592, 8-Bit/Farbe RGB, non-interlaced
        otago.jpg:JPEG-Bilddaten, EXIF-Standard 2.2
       waterfall.png:PNG-Bilddaten, 4608 x 2592, 8 Bit/Farbe RGB, Non-Interlaced

Sowohl das mehrzeilige als auch das einzeilige Format sind für Ihre Shell gleich und erzeugen genau die gleichen Ergebnisse.

Ein praktisches Beispiel

Hier ist ein praktisches Beispiel dafür, wie eine Schleife für die tägliche Computerarbeit nützlich sein kann. Angenommen, Sie haben eine Sammlung von Urlaubsfotos, die Sie an Freunde senden möchten. Ihre Fotodateien sind riesig, was sie zu groß zum Versenden per E-Mail und zu umständlich zum Hochladen auf Ihren Foto-Sharing-Dienst macht. Sie möchten kleinere Webversionen Ihrer Fotos erstellen, aber Sie haben 100 Fotos und möchten nicht die Zeit damit verschwenden, jedes Foto einzeln zu verkleinern.

Installieren Sie zuerst ImageMagick Befehl mit Ihrem Paketmanager unter Linux, BSD oder Mac. Zum Beispiel auf Fedora und RHEL:

$ sudo dnf install ImageMagick 

Unter Ubuntu oder Debian:

$ sudo apt install ImageMagick 

Verwenden Sie auf BSD Ports oder pkgsrc. Verwenden Sie auf dem Mac Homebrew oder MacPorts.

Sobald Sie ImageMagick installiert haben, verfügen Sie über eine Reihe neuer Befehle zum Bearbeiten von Fotos.

Erstellen Sie ein Zielverzeichnis für die Dateien, die Sie erstellen möchten:

$ mkdir tmp 

Probieren Sie diese Schleife aus, um jedes Foto auf 33 % seiner Originalgröße zu verkleinern:

$ for f in * ; do convert $f -scale 33% tmp/$f ; done 

Dann schauen Sie im tmp nach Ordner, um Ihre skalierten Fotos anzuzeigen.

Sie können eine beliebige Anzahl von Befehlen innerhalb einer Schleife verwenden. Wenn Sie also komplexe Aktionen für einen Stapel von Dateien ausführen müssen, können Sie Ihren gesamten Workflow zwischen den do platzieren und fertig Anweisungen eines for Schleife. Angenommen, Sie möchten jedes verarbeitete Foto direkt in ein freigegebenes Fotoverzeichnis auf Ihrem Webhost kopieren und die Fotodatei von Ihrem lokalen System entfernen:

$ für f in *; do 
    convert $f -scale 33% tmp/$f
    scp -i seth_web tmp/$f [email protected]:~/public_html
    trash tmp/$f;
  erledigt

Für jede Datei, die von for verarbeitet wird Schleife führt Ihr Computer automatisch drei Befehle aus. Das heißt, wenn Sie nur 10 Fotos auf diese Weise verarbeiten, sparen Sie sich 30 Befehle und wahrscheinlich mindestens genauso viele Minuten.

Limitiere deinen Loop

Eine Schleife muss sich nicht immer jede Datei ansehen. Möglicherweise möchten Sie nur die JPEG-Dateien in Ihrem Beispielverzeichnis verarbeiten:

$ für f in *.jpg; konvertieren Sie $f -scale 33% tmp/$f; erledigt
$ ls -m tmp
cat.jpg, otago.jpg

Anstatt Dateien zu verarbeiten, müssen Sie möglicherweise eine Aktion eine bestimmte Anzahl von Malen wiederholen. Ein für Die Variable der Schleife wird durch die von Ihnen bereitgestellten Daten definiert, sodass Sie eine Schleife erstellen können, die über Zahlen statt über Dateien iteriert:

$ für n in {0..4}; do echo $n; erledigt
0
1
2
3
4

Mehr Schleifen

Sie wissen jetzt genug, um Ihre eigenen Loops zu erstellen. Verwenden Sie sie für Kopien, bis Sie mit dem Schleifen vertraut sind der Dateien, die Sie verarbeiten möchten, und verwenden Sie so oft wie möglich Befehle mit integrierten Sicherheitsvorkehrungen, um zu verhindern, dass Sie Ihre Daten überfrachten und irreparable Fehler machen, wie z .

Für Fortgeschrittene für Schleifenthemen, lesen Sie weiter.

Nicht alle Shells sind Bash

Das für Das Schlüsselwort ist in die Bash-Shell integriert. Viele ähnliche Shells verwenden dasselbe Schlüsselwort und dieselbe Syntax, aber einige Shells, wie tcsh, verwenden ein anderes Schlüsselwort, wie foreach , stattdessen.

In tcsh ist die Syntax ähnlich, aber strenger als in Bash. Geben Sie im folgenden Codebeispiel nicht die Zeichenfolge foreach? ein in den Zeilen 2 und 3. Es ist eine sekundäre Eingabeaufforderung, die Sie darauf hinweist, dass Sie noch dabei sind, Ihre Schleife zu erstellen.

$ foreach f (*)
foreach? Datei $f
foreach? end
cat.jpg:JPEG-Bilddaten, EXIF-Standard 2.2
design_maori.png:PNG-Bilddaten, 4608 x 2592, 8-Bit/Farbe RGB, non-interlaced
otago.jpg:JPEG-Bilddaten, EXIF-Standard 2.2
waterfall.png:PNG-Bilddaten, 4608 x 2592, 8-Bit/Farbe RGB, non-interlaced

In tcsh sind beide foreach und Ende muss allein in separaten Zeilen erscheinen, daher können Sie kein for erstellen Schleife auf einer Zeile, wie Sie es mit Bash und ähnlichen Shells können.

For-Schleifen mit dem find-Befehl

Theoretisch könnten Sie eine Shell finden, die kein for bereitstellt Schleifenfunktion, oder Sie bevorzugen einfach einen anderen Befehl mit zusätzlichen Funktionen.

Der fund Befehl ist eine weitere Möglichkeit, die Funktionalität eines for zu implementieren -Schleife, da sie mehrere Möglichkeiten bietet, den Umfang zu definieren, welche Dateien in Ihre Schleife aufgenommen werden sollen, sowie Optionen für die parallele Verarbeitung.

Der fund Der Befehl soll Ihnen helfen, Dateien auf Ihren Festplatten zu finden. Seine Syntax ist einfach:Sie geben den Pfad des Ortes an, den Sie suchen möchten, und finden findet alle Dateien und Verzeichnisse:

$ finden . 
.
./cat.jpg
./design_maori.png
./otago.jpg
./waterfall.png

Sie können die Suchergebnisse filtern, indem Sie einen Teil des Namens hinzufügen:

$ finden . -name "*jpg"
./cat.jpg
./otago.jpg

Das Tolle an finden ist, dass jede gefundene Datei mit -exec in eine Schleife eingespeist werden kann Flagge. Um beispielsweise nur die PNG-Fotos in Ihrem Beispielverzeichnis zu verkleinern:

$ finden . -name "*png" -exec convert {} -scale 33% tmp/{} \;
$ ls -m tmp
design_maori.png, Wasserfall.png

In der -exec -Klausel, die Klammerzeichen {} Stelle dich für jeden Gegenstand ein, den du findest verarbeitet wird (mit anderen Worten, jede Datei mit der Endung PNG, die gefunden wurde, eine nach der anderen). Die -exec -Klausel muss mit einem Semikolon abgeschlossen werden, aber Bash versucht normalerweise, das Semikolon für sich selbst zu verwenden. Dem Semikolon "entkommen" Sie mit einem Backslash (\; ), damit finden weiß, dieses Semikolon als Abschlusszeichen zu behandeln.

Der fund command ist sehr gut in dem, was es tut, und es kann manchmal zu gut sein. Wenn Sie es beispielsweise erneut verwenden, um PNG-Dateien für einen anderen Fotoprozess zu finden, erhalten Sie einige Fehler:

$ finden . -name "*png" -exec convert {} -flip -flop tmp/{} \; 
Konvertieren:Bild `tmp/./tmp/design_maori.png' kann nicht geöffnet werden:
Keine solche Datei oder Verzeichnis @ error/blob.c/OpenBlob/2643.
...

Es scheint, dass finden hat alle PNG-Dateien gefunden – nicht nur die in Ihrem aktuellen Verzeichnis (. ), sondern auch solche, die Sie zuvor verarbeitet und in Ihr tmp abgelegt haben Unterverzeichnis. In manchen Fällen möchten Sie vielleicht finden um das aktuelle Verzeichnis und alle anderen darin enthaltenen Verzeichnisse (und alle Verzeichnisse in diesen) zu durchsuchen ). Es kann ein mächtiges rekursives Verarbeitungswerkzeug sein, besonders in komplexen Dateistrukturen (wie Verzeichnisse von Musikkünstlern, die Verzeichnisse von Alben enthalten, die mit Musikdateien gefüllt sind), aber Sie können dies mit -maxdepth einschränken Option.

So finden Sie nur PNG-Dateien im aktuellen Verzeichnis (ohne Unterverzeichnisse):

$ find . -maxdepth 1 -name "*png" 

Um Dateien im aktuellen Verzeichnis plus einer zusätzlichen Ebene von Unterverzeichnissen zu finden und zu verarbeiten, erhöhen Sie die maximale Tiefe um 1:

$ find . -maxdepth 2 -name "*png" 

Seine Standardeinstellung ist, in alle Unterverzeichnisse abzusteigen.

Looping für Spaß und Profit

Je mehr Sie Schleifen verwenden, desto mehr Zeit und Mühe sparen Sie und desto größere Aufgaben können Sie bewältigen. Sie sind nur ein Benutzer, aber mit einer gut durchdachten Schleife können Sie Ihren Computer die harte Arbeit erledigen lassen.

Sie können und sollten Schleifen wie jeden anderen Befehl behandeln und ihn griffbereit haben, wenn Sie eine oder zwei einzelne Aktionen für mehrere Dateien wiederholen müssen. Es ist jedoch auch ein legitimes Tor zu seriöser Programmierung. Wenn Sie also eine komplexe Aufgabe für eine beliebige Anzahl von Dateien ausführen müssen, nehmen Sie sich einen Moment Zeit, um Ihren Arbeitsablauf zu planen. Wenn Sie Ihr Ziel mit einer Datei erreichen können, packen Sie diesen wiederholbaren Prozess in ein for Schleife ist relativ einfach, und die einzige erforderliche "Programmierung" ist ein Verständnis dafür, wie Variablen funktionieren, und genügend Organisation, um unverarbeitete von verarbeiteten Dateien zu trennen. Mit ein wenig Übung können Sie sich von einem Linux-Benutzer zu einem Linux-Benutzer entwickeln, der weiß, wie man eine Schleife schreibt, also gehen Sie raus und lassen Sie Ihren Computer für sich arbeiten!


Linux
  1. So verwenden Sie Bash-Verlaufsbefehle

  2. Wie debuggt man ein Bash-Skript?

  3. Wie erkennt man Bash>=4.0?

  4. Wie schreibe ich mit Bash Integer in eine Binärdatei?

  5. So erhalten Sie den Exit-Status in einer Bash-Schleife

Bash-while-Schleife

Bash für Schleife

Bash bis Loop

Bash-Scripting:So schreiben Sie Daten in Textdateien

Shell-Scripting für Anfänger – So schreiben Sie Bash-Scripts unter Linux

So führen Sie ein Bash-Skript aus