der Leitfaden für Anfänger zur Shell-Scripting 2: for-Schleifen

Wenn Sie Ihren Aussenseiter cred aufbauen wollen, besuchen Sie uns für die zweite Tranche in unserem Shell-Scripting-Serie. Wir haben ein paar Korrekturen, einige Verbesserungen der letzten Woche Skript und eine Anleitung für den Uneingeweihten Looping.

In der ersten Tranche unserer Shell-Scripting Guide, haben wir ein Skript, das eine Datei in ein Backup-Verzeichnis nach Anhängen das Datum an das Ende des Dateinamens kopiert.

Samuel Dionne-Riel wies in den Kommentaren darauf hin, dass es eine viel bessere Möglichkeit, unsere Variablenreferenzen zu handhaben.

Die Argumente sind durch Leerzeichen getrennt in die Bash-Shell, wird es tokenize, wenn es einen Raum, in dem resultierenden erweiterten Befehl ist. In Ihrem Skript cp $ 1 $ 2 $ date_formatted wie beabsichtigt funktionieren, solange die erweiterten Variablen haben keine Leerzeichen enthalten. Wenn Sie Ihr Skript auf diese Weise nennen: datecp “meinen alten Namen” “mein neuer Name” die Expansion in diesem Befehl führen wird: meine alte name.the_date cp meinen neuen Namen, der eigentlich 6 Argumente hat.

Um richtig dieses Problem zu beheben, sollte die letzte Zeile des Skripts sein: cp “$ 1” “2 $ $ date_formatted

Wie Sie sehen können, Ändern Linie unsere Skripts aus

cp -IV $ 1 $ 2 $ date_formatted

nach

cp -IV “$ 1” “$ 2”. $ date_formatted

wird dieses Problem kümmern, wenn das Skript auf Dateien verwenden, die Leerzeichen im Namen haben. Samuel macht auch den Punkt, dass beim Kopieren und Einfügen von Code von dieser Seite (oder das Internet im Allgemeinen) darauf, die richtigen Striche und Zitate für die “typographisch besser” diejenigen zu ersetzen, die sie oft zu ersetzen. Wir werden auch mehr tun, unseren Code, um sicherzustellen, mehr copy / paste freundlich ist. 😉

Ein weiterer Kommentator, Myles Braithwaite, entschied sich unser Skript zu erweitern, so dass das Datum vor der Dateierweiterung erscheinen würde. Also statt

tastyfile.mp3.07_14_11-12.34.56

wir bekommen würden diese

tastyfile.07_14_11-12.34.56.mp3

die endet als ein wenig bequemer für die meisten Anwender. Sein Code ist auf seiner GitHub Seite zur Verfügung. Lassen Sie uns einen Blick darauf werfen, was er verwendet den Dateinamen auseinander zu ziehen.

date_formatted = $ (date +% Y-% m-% d_% H.% M% S); file_extension = $ (echo “$ 1” | awk -F ‘{print $ NF}.’); file_name = $ (base $ 1 $ file_extension)

cp -IV $ 1 $ file_name- $ date_formatted. $ file_extension

Ich habe das ein bisschen Formatierung geändert, aber man kann sehen, dass Myles seine Datumsfunktion in der Linie 1 in Zeile 2 erklärt er jedoch verwendet das “Echo” Befehl mit dem ersten Argument des Skripts der Datei-Namen ausgegeben. Er nutzt die Pipe-Befehl, dass die Ausgabe zu nehmen und sie als Eingabe für den nächsten Teil verwenden. Nach dem Rohr, ruft Myles auf den “awk” Befehl, der ein leistungsfähiges Muster Scan-Programm ist. Mit der Option -F, er erzählt den Befehl, dass das nächste Zeichen (nach einem Leerzeichen) ist das, was die “Feldtrennzeichen” definieren wird. In diesem Fall ist, dass eine Periode.

Nun sehen, awk eine Datei mit dem Namen “tastyfile.mp3”, wie aus zwei Feldern zusammengesetzt ist: “tastyfile” und “mp3”. Schließlich nutzt er

‘{Print $ NF}’

das letzte Feld angezeigt werden soll. Für den Fall, hat Ihre Datei mehrere Perioden – daher macht awk sehen mehrere Felder – es wird nur die letzte Anzeige, die die Dateierweiterung.

In Zeile 3, schafft er eine neue Variable für den Namen der Datei und verwendet die “Basis- name”, Befehl alles in $ 1, mit Ausnahme der Dateierweiterung zu verweisen. Dies wird durch die Verwendung von Basisnamen gemacht und es $ 1 als Argument geben, dann ein Leerzeichen und die Dateierweiterung hinzufügen. Die Dateierweiterung wird automatisch aufgrund der Variable hinzugefügt, die Linie verweist 2. Was dies tun würde, ist nehmen

tastyfile.mp3

und es in

tastyfile

Dann in der letzten Zeile, Myles zusammengestellt den Befehl, das wird alles ausgeben, um. Beachten Sie, dass kein Verweis dort für das Skript zu $ ​​2 ein zweites Argument ist. Diese besondere Skript kopiert die Datei in das aktuelle Verzeichnis statt. Great job Samuel und Myles!

Wir erwähnen auch in unseren Basics Artikel, die Skripts nicht erlaubt werden als Befehle standardmäßig referenziert werden. Das heißt, Sie müssen den Pfad des Skripts, um zu zeigen, um sie auszuführen

/Skript

~ / Bin / script

Aber, indem Sie Ihre Skripte in ~ / bin / platzieren, könnten Sie einfach ihren Namen eingeben von überall zu bekommen, sie laufen zu.

Commen einige Zeit debattieren verbrachte, wie die richtige war, da keine moderne Linux-Distribution das Verzeichnis standardmäßig erstellt. Darüber hinaus fügt sie niemand auf die $ PATH-Variable standardmäßig entweder, das ist das, was in Ordnung erforderlich ist für Skripte wie Befehle ausgeführt werden. Ich war ein wenig verwirrt, weil nach meiner $ PATH-Variable überprüft, die commen richtig waren, aber Aufruf Skripte noch funktionierte für mich. Ich fand heraus, warum: viele moderne Linux-Distributionen eine spezielle Datei im Home-Verzeichnis des Benutzers -.profile erstellen.

Diese Datei wird von bash gelesen (unless.bash_profile ist in das Home-Verzeichnis des Benutzers) und an der Unterseite gibt es einen Abschnitt, der die ~ / bin / Ordner, um die $ PATH-Variable hinzufügt, wenn es vorhanden ist. So ist das Geheimnis aufgeklärt. Für den Rest der Serie werde ich auch weiterhin Skripte in der ~ / bin / Verzeichnis platzieren, weil sie Benutzerskripts sind und sollten von den Benutzern ausgeführt werden können. Und es scheint, dass wir nicht wirklich mit der $ PATH-Variable von Hand zu Chaos brauchen die Dinge zum Laufen zu bringen.

Lassen Sie uns für den Umgang mit sich wiederholende Aufgaben zu einer der nützlichsten Werkzeuge in den Aussenseiter Arsenal bekommen: Schleifen. Heute werden wir “für” Schleifen diskutieren.

Die Grundzüge einer for-Schleife ist wie folgt

für die Variable in List, tun; command1; command2; …; commandn; getan

Variable kann eine Variable sein, obwohl die meisten oft die kleinen “i” vereinbarungsgemäß verwendet wird. Liste ist eine Liste der Elemente, mehrere Elemente angeben können, zeigen Sie auf einer externen Textdatei (sie durch ein Leerzeichen zu trennen) oder ein Sternchen (*) alle Dateien im aktuellen Verzeichnis zu bezeichnen. Die Befehle aufgelistet sind durch Konvention eingekerbt, so ist es leichter zu sehen, nisten – Putting Schleifen in Schleifen (so können Sie Schleife, während Sie Schleife).

Da Listen Leerzeichen als Trennzeichen verwenden – das heißt, bedeutet ein Raum eine Bewegung zum nächsten Eintrag in der Liste – Dateien, die Leerzeichen im Namen sind nicht sehr freundlich sind. Vorerst bleiben wir mit Dateien ohne spaces.Let den Anfang mit einem einfachen Skript zu arbeiten, um die Namen der Dateien im aktuellen Verzeichnis angezeigt werden soll. Erstellen Sie ein neues Skript in ~ / bin / Ordner mit dem Namen “Zyklusskript”. Wenn Sie nicht daran erinnern, wie dies zu tun (einschließlich es als ausführbare Markierung und das Hinzufügen der Hash-Bang-Hack) beziehen sich auf unsere Bash Scripting Grundlagen Artikel.

Darin geben Sie den folgenden Code

für i in item1 item2 item3 item4 item5 Item6, tun; echo “$ i”; getan

Wenn Sie das Skript ausführen, sollten Sie nur diese Listenelemente als Ausgabe zu erhalten.

Ziemlich einfach, nicht wahr? Mal sehen, was passiert, wenn wir die Dinge ein wenig ändern. Ändern Sie Ihr Skript, so dass es das sagt

in * i, tun; echo “$ i”; getan

Wenn Sie dieses Skript in einem Ordner ausführen, sollten Sie eine Liste von Dateien zu erhalten, die es als Ausgabe enthält.

Nun lassen Sie uns den Befehl echo ändern in etwas mehr nützlich – sagen wir, der Zip-Befehl. Das heißt, wir werden Dateien in einem Archiv hinzufügen. Und lassen Sie uns einige Argumente in der Mischung bekommt!

für i @ in $, tun; ZIP-Archiv “$ i”; done

Es gibt etwas Neues! “$ @” Ist eine Abkürzung für “$ 1 $ 2 $ 3 … $ n”. Mit anderen Worten, es ist die volle Liste aller Argumente, die Sie angegeben haben. Nun, sehen Sie, was passiert, wenn ich das Skript mit mehreren Eingabedateien ausführen.

Sie können, welche Dateien in meinem Ordner. Ich lief den Befehl mit sechs Argumente, und jede Datei in ein ZIP-Archiv mit dem Namen “archive.zip” wurde hinzugefügt. Einfach, nicht wahr?

Für Schleifen sind ziemlich wunderbar. Jetzt können Sie Batch-Funktionen auf Listen von Dateien auszuführen. Zum Beispiel können Sie alle Ihre Skript Argumente in ein ZIP-Archiv, bewegen Sie die Originale in einen anderen Ordner kopieren und automatisch eine sichere Kopie, die Datei auf einem Remote-Computer zip. Wenn Sie Schlüsseldateien mit SSH einrichten, werden Sie nicht einmal müssen Sie Ihr Passwort eingeben, und Sie können sogar das Skript anweisen, die Zip-Datei nach dem Hochladen zu löschen!

Unter Verwendung for-Schleifen macht es einfach, eine Reihe von Aktionen für alle Dateien in einem Verzeichnis zu tun. Sie können eine Vielzahl von Befehlen stapeln zusammen und Argumente verwenden sehr einfach zu erstellen und on-the-fly-Liste, und das ist nur die Spitze des Eisbergs.

Bash Scripter, haben Sie irgendwelche Vorschläge? Hast du ein nützliches Skript, das Schleifen verwendet? Wollen Sie Gedanken über die Serie zu teilen? Lassen Sie einige Kommentare und helfen Sie anderen Scripting-Neulingen aus!

Für jeden, der will mit Teilzeichenfolge Entfernung und Isolierung zu arbeiten, würde ich scheuen externen Dienstprogramme weg, da es einige (minimal) Performance Kosten verursacht. Der wahre Grund von externen Tools zu scheuen ist nicht einige externe Abhängigkeiten zwingen, wenn sie nicht benötigt.

Wie gesagt, kann String alle innerhalb bash erfolgen. Hier ist ein Zitat mit Beispielen aus der bash-Hacker Wiki

—- QUOTE START —-

Wie zum Teufel tut, dass Hilfe mein Leben einfacher zu machen?

Na ja, vielleicht die häufigste Verwendung für sie ist, Teile eines Dateinamens zu extrahieren. Schauen Sie sich die folgende Liste mit Beispielen

Erhalten Sie Name ohne Erweiterung; $ {filename% *.}; ⇒ bash_hackers.txt

Holen Verlängerung; $ {filename ## *.}; ⇒ bash_hackers.txt

Erhalten Sie Verzeichnisname; $ {PATHNAME% / *}; ⇒ /home/bash/bash_hackers.txt

Erhalten Sie Dateiname, $ {PATHNAME ## * /}; ⇒ /home/bash/bash_hackers.txt

Dies sind die Schreibweisen für Dateinamen mit einem einzigen Erweiterung. Je nach Bedarf, müssen Sie möglicherweise kürzeste / längste Spiel einzustellen.

—- ZITAT ENDE —-

Hoffe, dass dies jemand helfen kann, da die Syntax robuster ist. Sie können auch mehr darum kümmern, indem auf die Parameter-Erweiterung Seite des bash-Hacker Wiki gehen.

Aber Basisnamen tastyfile.mp3 returns “tastyfile” und file_extension ist “mp3”;. So file_name = $ (basename $ 1. $ file_extension) macht datei_name den Wert “tastyfile.mp3” nehmen, das heißt die gleiche wie 1 $.

Sie sollten sagen, file_name = $ (basename $ 1 – $ date_formatted $ file_extension.)

cp -IV $ 1 $ file_name

Sie könnten mit einem anderen Skriptsprache zu bleiben möchten, gibt es alle Arten von Fehlern in diesem Tutorial.

warum bearbeiten in nano ich VIM abwehren, um mehr benutzerfreundlich sein

wieder sehr gut Artikel geschrieben.

HTG Rocks !! \ M /

Peter Shea ist falsch;. Basisnamen tastyfile.mp3.mp3; Erträge; tastyfile

Aibohphobia ist der Begriff für die irrationale Angst vor Palindrome und ist mit Absicht Palindrom.