Content from Einführung in die Shell
Zuletzt aktualisiert am 2025-10-23 | Diese Seite bearbeiten
Übersicht
Fragen
- Was ist eine Befehlsshell und warum sollte ich sie benutzen?
Ziele
- Erklären Sie, wie die Shell mit der Tastatur, dem Bildschirm, dem Betriebssystem und den Programmen der Benutzer zusammenhängt.
- Erklären Sie, wann und warum Befehlszeilenschnittstellen anstelle von grafischen Schnittstellen verwendet werden sollten.
Hintergrund
Menschen und Computer interagieren in der Regel auf viele verschiedene Arten, z. B. über Tastatur und Maus, Touchscreen-Schnittstellen oder mit Spracherkennungssystemen. Die am weitesten verbreitete Art der Interaktion mit Personalcomputern ist die grafische Benutzeroberfläche (GUI). Bei einer GUI werden Anweisungen per Mausklick und über menügesteuerte Interaktionen erteilt.
Während die visuelle Hilfe einer grafischen Benutzeroberfläche das Erlernen intuitiv macht, lässt sich diese Art der Übermittlung von Anweisungen an einen Computer nur sehr schlecht skalieren. Stellen Sie sich folgende Aufgabe vor: Für eine Literaturrecherche müssen Sie die dritte Zeile von eintausend Textdateien in eintausend verschiedenen Verzeichnissen kopieren und in eine einzige Datei einfügen. Mit einer grafischen Benutzeroberfläche würden Sie nicht nur stundenlang an Ihrem Schreibtisch herumklicken, sondern möglicherweise auch einen Fehler bei der Erledigung dieser sich wiederholenden Aufgabe begehen. An dieser Stelle kommt die Unix-Shell zum Einsatz. Die Unix-Shell ist sowohl eine Befehlszeilenschnittstelle (CLI) als auch eine Skriptsprache, mit der solche sich wiederholenden Aufgaben automatisch und schnell erledigt werden können. Mit den richtigen Befehlen kann die Shell Aufgaben mit oder ohne Änderungen so oft wiederholen, wie wir wollen. Mit der Shell kann die Aufgabe im Literaturbeispiel in Sekundenschnelle erledigt werden.
Die Shell
Die Shell ist ein Programm, in das Benutzer Befehle eingeben können. Mit der Shell ist es möglich, komplizierte Programme wie Klimamodellierungssoftware aufzurufen oder einfache Befehle, die ein leeres Verzeichnis mit nur einer Zeile Code erstellen. Die populärste Unix-Shell ist Bash (die Bourne Again SHell — so genannt, weil sie von einer Shell abgeleitet ist, die von Stephen Bourne geschrieben wurde). Bash ist die Standard-Shell in den meisten modernen Unix-Implementierungen und in den meisten Paketen, die Unix-ähnliche Werkzeuge für Windows bereitstellen. Beachten Sie, dass “Git Bash” eine Software ist, die es Windows-Benutzern ermöglicht, eine Bash-ähnliche Schnittstelle für die Interaktion mit Git zu verwenden.
Die Verwendung der Shell erfordert einige Mühe und Zeit, um sie zu erlernen. Während eine grafische Benutzeroberfläche (GUI) Ihnen Auswahlmöglichkeiten bietet, werden diese bei der Befehlszeilenschnittstelle (CLI) nicht automatisch angeboten, so dass Sie einige Befehle wie neue Vokabeln in einer Sprache, die Sie lernen, lernen müssen. Anders als bei einer gesprochenen Sprache reicht jedoch eine kleine Anzahl von “Wörtern” (d. h. Befehlen) aus, um weit zu kommen, und wir werden uns heute mit diesen wenigen wichtigen Wörtern beschäftigen.
Die Grammatik einer Shell ermöglicht es Ihnen, vorhandene Tools zu leistungsfähigen Pipelines zu kombinieren und große Datenmengen automatisch zu verarbeiten. Sequenzen von Befehlen können in ein Skript geschrieben werden, was die Reproduzierbarkeit von Arbeitsabläufen verbessert.
Darüber hinaus ist die Kommandozeile oft die einfachste Möglichkeit, mit entfernten Rechnern und Supercomputern zu interagieren. Die Vertrautheit mit der Shell ist nahezu unverzichtbar, um eine Vielzahl von spezialisierten Tools und Ressourcen, einschließlich Hochleistungscomputersystemen, zu nutzen. Da Cluster und Cloud-Computing-Systeme für die wissenschaftliche Datenverarbeitung immer beliebter werden, wird die Fähigkeit, mit der Shell zu interagieren, zu einer notwendigen Fähigkeit. Wir können auf den hier behandelten Kommandozeilenfähigkeiten aufbauen, um eine breite Palette wissenschaftlicher Fragen und rechnerischer Herausforderungen anzugehen.
Fangen wir an.
Wenn die Shell zum ersten Mal geöffnet wird, erscheint ein Prompt, das anzeigt, dass die Shell auf Eingaben wartet.
Die Shell verwendet normalerweise $ als
Eingabeaufforderung, kann aber auch ein anderes Symbol verwenden. In den
Beispielen dieser Lektion zeigen wir den Prompt als $. Am
wichtigsten ist, dass Sie nicht den Prompt eingeben, wenn Sie
Befehle eingeben. Geben Sie nur den Befehl ein, der auf die
Eingabeaufforderung folgt. Diese Regel gilt sowohl in dieser Lektion als
auch in Lektionen aus anderen Quellen. Beachten Sie auch, dass Sie,
nachdem Sie einen Befehl eingegeben haben, die Eingabetaste
drücken müssen, um ihn auszuführen.
Auf die Eingabeaufforderung folgt ein Textcursor, ein Zeichen, das die Position angibt, an der Ihre Eingaben erscheinen werden. Der Cursor ist normalerweise ein blinkender oder fester Block, kann aber auch ein Unterstrich oder eine Pipe sein. Sie haben ihn vielleicht schon einmal in einem Texteditor-Programm gesehen, zum Beispiel
Beachten Sie, dass Ihre Eingabeaufforderung ein wenig anders aussehen
könnte. Insbesondere setzen die meisten gängigen Shell-Umgebungen
standardmäßig Ihren Benutzernamen und den Rechnernamen vor das
$. Eine solche Eingabeaufforderung könnte z.B. so
aussehen:
Die Eingabeaufforderung kann sogar noch mehr als das enthalten.
Machen Sie sich keine Sorgen, wenn Ihr Prompt nicht nur aus einem kurzen
$ besteht. Diese Lektion hängt nicht von diesen
zusätzlichen Informationen ab, und sie sollten Ihnen auch nicht im Weg
stehen. Der einzige wichtige Punkt, auf den Sie sich konzentrieren
sollten, ist das Zeichen $ selbst, und wir werden später
sehen, warum.
Versuchen wir es also mit unserem ersten Befehl, ls, was
kurz für listing (also “auflisten”) ist. Dieser Befehl listet den Inhalt
des aktuellen Verzeichnisses auf:
AUSGABE
Desktop Downloads Movies Pictures
Documents Library Music Public
Befehl nicht gefunden
Nelle’s Pipeline: Ein typisches Problem
Nelle Nemo, eine Meeresbiologin, ist gerade von einer sechsmonatigen
Untersuchung des Nordpazifischen
Wirbels zurückgekehrt, wo sie Proben von gallertartigen
Meereslebewesen im Great
Pacific Garbage Patch genommen hat. Sie hat 1520 Proben, die sie
durch ein Testgerät laufen ließ, um die relative Häufigkeit von 300
Proteinen zu messen. Sie muss diese 1520 Dateien durch ein imaginäres
Programm namens goostats.sh laufen lassen. Zusätzlich zu
dieser riesigen Aufgabe muss sie die Ergebnisse bis Ende des Monats
aufschreiben, damit ihr Artikel in einer Sonderausgabe der Aquatic
Goo Letters erscheinen kann.
Wenn Nelle sich dafür entscheidet, goostats.sh von Hand
über eine grafische Benutzeroberfläche auszuführen, muss sie eine Datei
1520 Mal auswählen und öffnen. Wenn goostats.sh 30 Sekunden
braucht, um jede Datei auszuführen, wird der gesamte Prozess mehr als 12
Stunden von Nelles Aufmerksamkeit in Anspruch nehmen. Mit der Shell kann
Nelle stattdessen ihrem Computer diese banale Aufgabe übertragen,
während sie sich auf das Schreiben ihrer Arbeit konzentriert.
In den nächsten Lektionen wird untersucht, wie Nelle dies erreichen
kann. Genauer gesagt, wird in den Lektionen erklärt, wie sie eine
Befehlsshell verwenden kann, um das Programm goostats.sh
auszuführen, wobei Schleifen verwendet werden, um die sich
wiederholenden Schritte der Eingabe von Dateinamen zu automatisieren, so
dass ihr Computer arbeiten kann, während sie ihre Arbeit schreibt.
Wenn sie einmal eine Verarbeitungspipeline zusammengestellt hat, kann sie diese bei jeder weiteren Datenerfassung wieder verwenden.
Um ihre Aufgabe zu erfüllen, muss Nelle wissen, wie man:
- zu einer Datei/Verzeichnis navigieren
- Erstellen einer Datei/eines Verzeichnisses
- Prüfen der Länge einer Datei
- Befehle aneinanderreihen
- Abrufen einer Reihe von Dateien
- Iteration über Dateien
- ein Shell-Skript ausführen, das ihre Pipeline enthält
- Eine Shell ist ein Programm, dessen Hauptzweck darin besteht, Befehle zu lesen und andere Programme auszuführen.
- Diese Lektion verwendet Bash, die Standard-Shell in vielen Unix-Implementierungen.
- Programme können in der Bash durch Eingabe von Befehlen an der Eingabeaufforderung ausgeführt werden.
- Die Hauptvorteile der Shell sind ihr hohes Verhältnis von ausgeführten Aktionen zu Tasteneingaben, ihre Unterstützung bei der Automatisierung wiederkehrender Aufgaben und ihre Fähigkeit, auf vernetzte Rechner zuzugreifen.
- Eine große Herausforderung bei der Verwendung der Shell kann darin bestehen, zu wissen, welche Befehle ausgeführt werden müssen und wie sie auszuführen sind.
Content from Dateien und Verzeichnisse durchsuchen
Zuletzt aktualisiert am 2025-10-23 | Diese Seite bearbeiten
Übersicht
Fragen
- Wie kann ich mich auf meinem Computer bewegen?
- Wie kann ich sehen, welche Dateien und Verzeichnisse ich habe?
- Wie kann ich den Ort einer Datei oder eines Verzeichnisses auf meinem Computer angeben?
Ziele
- Erkläre die Gemeinsamkeiten und Unterschiede zwischen einer Datei und einem Verzeichnis.
- Übersetzt einen absoluten Pfad in einen relativen Pfad und umgekehrt.
- Konstruieren Sie absolute und relative Pfade, die bestimmte Dateien und Verzeichnisse identifizieren.
- Verwenden Sie Optionen und Argumente, um das Verhalten eines Shell-Befehls zu ändern.
- Demonstrieren Sie die Verwendung der Tabulatorvervollständigung und erklären Sie ihre Vorteile.
Der Teil des Betriebssystems, der für die Verwaltung von Dateien und Verzeichnissen zuständig ist, wird Dateisystem genannt. Es organisiert unsere Daten in Dateien, die Informationen enthalten, und Verzeichnissen (auch ‘Ordner’ genannt), die Dateien oder andere Verzeichnisse enthalten.
Mehrere Befehle werden häufig zum Erstellen, Überprüfen, Umbenennen und Löschen von Dateien und Verzeichnissen verwendet. Um sie zu erforschen, gehen wir zu unserem geöffneten Shell-Fenster.
Zuerst wollen wir herausfinden, wo wir uns befinden, indem wir einen
Befehl namens pwd ausführen (das steht für ‘print working
directory’). Verzeichnisse sind wie Orte - zu jeder Zeit,
während wir die Shell benutzen, sind wir an genau einem Ort, der unser
aktuelles Arbeitsverzeichnis genannt wird. Die meisten
Befehle lesen und schreiben Dateien im aktuellen Arbeitsverzeichnis,
d.h. ‘hier’, daher ist es wichtig zu wissen, wo man sich befindet, bevor
man einen Befehl ausführt.pwd zeigt Ihnen, wo Sie sich
befinden:
AUSGABE
/Users/nelle
Hier ist die Antwort des Computers /Users/nelle, was
Nelles Home-Verzeichnis ist:
Variation des Homeverzeichnisses
Der Pfad zum Homeverzeichnis sieht auf verschiedenen Betriebssystemen
unterschiedlich aus. Unter Linux kann er wie /home/nelle
aussehen, und unter Windows wird er ähnlich wie
C:\Documents and Settings\nelle oder
C:\Users\nelle sein. (Beachten Sie, dass es bei
verschiedenen Windows-Versionen etwas anders aussehen kann.) In den
zukünftigen Beispielen haben wir die Mac-Ausgabe als Standard verwendet
- die Linux- und Windows-Ausgabe kann leicht abweichen, sollte aber im
Allgemeinen ähnlich sein.
Wir nehmen auch an, dass Ihr pwd-Befehl das
Homeverzeichnis Ihres Benutzers zurückgibt. Wenn pwd etwas
anderes zurückgibt, müssen Sie möglicherweise mit cd
dorthin navigieren, oder einige Befehle in dieser Lektion werden nicht
wie geschrieben funktionieren. Siehe Andere Verzeichnisse erforschen
für weitere Details über den cd Befehl.
Um zu verstehen, was ein “Homeverzeichnis” ist, schauen wir uns an, wie das Dateisystem als Ganzes organisiert ist. Für dieses Beispiel werden wir das Dateisystem auf dem Computer unserer Wissenschaftlerin Nelle darstellen. Nach dieser Veranschaulichung werden Sie Befehle lernen, um Ihr eigenes Dateisystem zu erforschen, das ähnlich aufgebaut sein wird, aber nicht exakt identisch ist.
Auf Nelle’s Computer sieht das Dateisystem wie folgt aus:
Das Dateisystem sieht aus wie ein auf dem Kopf stehender Baum. Das
oberste Verzeichnis ist das Rootverzeichnis, das alles
andere enthält. Wir verweisen auf es mit einem Schrägstrich,
/, allein; dieses Zeichen ist der führende Schrägstrich in
/Users/nelle.
Innerhalb dieses Verzeichnisses gibt es mehrere andere Verzeichnisse:
bin (in dem einige eingebaute Programme gespeichert
werden), data (für verschiedene Datendateien),
Users (in dem sich die persönlichen Verzeichnisse der
Benutzer befinden), tmp (für temporäre Dateien, die nicht
langfristig gespeichert werden müssen), und so weiter.
Wir wissen, dass unser aktuelles Arbeitsverzeichnis
/Users/nelle innerhalb von /Users gespeichert
ist, weil /Users der erste Teil seines Namens ist. Ebenso
wissen wir, dass /Users innerhalb des Stammverzeichnisses
/ gespeichert ist, weil sein Name mit /
beginnt.
Schrägstriche
Beachten Sie, dass es zwei Bedeutungen für das Zeichen /
gibt. Wenn es am Anfang eines Datei- oder Verzeichnisnamens erscheint,
bezieht es sich auf das Stammverzeichnis. Wenn es innerhalb
eines Pfades erscheint, ist es nur ein Trennzeichen.
Unterhalb von /Users finden wir ein Verzeichnis für
jeden Benutzer mit einem Konto auf Nelles Rechner, ihre Kollegen
imhotep und larry.
{alt=“Wie andere Verzeichnisse
sind Home-Verzeichnisse Unterverzeichnisse unterhalb von”/Users” wie
“/Users/imhotep”, “/Users/larry” oder”/Users/nelle”“}
Die Dateien des Benutzers imhotep werden in
/Users/imhotep gespeichert, die des Benutzers
larry in /Users/larry und die von Nelle in
/Users/nelle. Nelle ist der Benutzer in unseren Beispielen
hier; daher bekommen wir /Users/nelle als unser
Homeverzeichnis. Wenn Sie eine neue Eingabeaufforderung öffnen, befinden
Sie sich normalerweise zunächst in Ihrem Homeverzeichnis.
Jetzt wollen wir den Befehl lernen, mit dem wir den Inhalt unseres
eigenen Dateisystems sehen können. Wir können sehen, was sich in unserem
Homeverzeichnis befindet, indem wir ls ausführen:
AUSGABE
Applications Documents Library Music Public
Desktop Downloads Movies Pictures
(Auch hier können die Ergebnisse leicht abweichen, je nachdem, wie Sie Ihr Dateisystem angepasst haben und unter welchem Betriebssystem Sie arbeiten)
ls gibt die Namen der Dateien und Verzeichnisse im
aktuellen Verzeichnis aus. Wir können die Ausgabe verständlicher machen,
indem wir die Option -F verwenden, die
ls anweist, die Ausgabe zu klassifizieren, indem es den
Datei- und Verzeichnisnamen eine Markierung hinzufügt, um anzuzeigen,
worum es sich handelt:
- ein nachgestelltes
/zeigt an, dass dies ein Verzeichnis ist -
@zeigt einen Link an -
*zeigt eine ausführbare Datei an
Abhängig von den Standardeinstellungen Ihrer Shell, kann die Shell auch Farben verwenden, um anzuzeigen, ob jeder Eintrag eine Datei oder ein Verzeichnis ist.
AUSGABE
Applications/ Documents/ Library/ Music/ Public/
Desktop/ Downloads/ Movies/ Pictures/
Hier können wir sehen, dass das Homeverzeichnis nur Unterverzeichnisse enthält. Alle Namen in der Ausgabe, die kein Klassifizierungssymbol haben, sind Dateien im aktuellen Arbeitsverzeichnis.
Löschen des Terminals
Wenn Ihr Bildschirm zu unübersichtlich wird, können Sie Ihr Terminal
mit dem Befehl clear leeren. Du kannst immer noch auf
vorherige Befehle zugreifen, indem du ↑ und ↓
verwendest, um dich Zeile für Zeile zu bewegen, oder indem du in deinem
Terminal scrollst.
Hilfe erhalten
ls hat eine Menge anderer Optionen. Es
gibt zwei übliche Wege, um herauszufinden, wie man einen Befehl benutzt
und welche Optionen er akzeptiert — Abhängig von Ihrer Umgebung
könnten Sie feststellen, dass nur einer dieser Wege
funktioniert:
- Wir können die Option
--helpan jeden Befehl übergeben (verfügbar unter Linux und Git Bash), zum Beispiel:
- Wir können sein Handbuch mit
manlesen (verfügbar unter Linux und macOS):
Wir werden beide Möglichkeiten im Folgenden beschreiben.
Hilfe für eingebaute Befehle
Einige Befehle sind in die Bash-Shell eingebaut, anstatt als separate
Programme im Dateisystem zu existieren. Ein Beispiel ist der Befehl
cd (Verzeichnis wechseln). Wenn Sie eine Meldung wie
No manual entry for cd erhalten, versuchen Sie stattdessen
help cd. Mit dem Befehl help erhalten Sie
Nutzungsinformationen für Bash
built-ins.
Die --help Option
Die meisten Bash-Befehle und -Programme, die für die Ausführung
innerhalb der Bash geschrieben wurden, unterstützen eine Option
--help, die weitere Informationen zur Verwendung des
Befehls oder Programms anzeigt.
AUSGABE
Usage: ls [OPTION]... [FILE]...
List information about the FILEs (the current directory by default).
Sort entries alphabetically if neither -cftuvSUX nor --sort is specified.
Mandatory arguments to long options are mandatory for short options, too.
-a, --all do not ignore entries starting with .
-A, --almost-all do not list implied . and ..
--author with -l, print the author of each file
-b, --escape print C-style escapes for nongraphic characters
--block-size=SIZE scale sizes by SIZE before printing them; e.g.,
'--block-size=M' prints sizes in units of
1,048,576 bytes; see SIZE format below
-B, --ignore-backups do not list implied entries ending with ~
-c with -lt: sort by, and show, ctime (time of last
modification of file status information);
with -l: show ctime and sort by name;
otherwise: sort by ctime, newest first
-C list entries by columns
--color[=WHEN] colorize the output; WHEN can be 'always' (default
if omitted), 'auto', or 'never'; more info below
-d, --directory list directories themselves, not their contents
-D, --dired generate output designed for Emacs' dired mode
-f do not sort, enable -aU, disable -ls --color
-F, --classify append indicator (one of */=>@|) to entries
... ... ...
Wann man kurze oder lange Optionen verwenden sollte
Wenn Optionen sowohl als kurze als auch als lange Optionen existieren:
- Verwenden Sie die Option short, wenn Sie Befehle direkt in die Shell eingeben, um die Anzahl der Tastenanschläge zu minimieren und Ihre Aufgabe schneller zu erledigen.
- Verwenden Sie die Option long in Skripten, um Klarheit zu schaffen. Sie wird viele Male gelesen und nur einmal eingegeben.
Der man Befehl
Die andere Möglichkeit, etwas über ls zu erfahren, ist
die Eingabe von
Dieser Befehl verwandelt Ihr Terminal in eine Seite mit einer
Beschreibung des Befehls ls und seiner Optionen.
Um durch die man-Seiten zu navigieren, können Sie
↑ und ↓ benutzen, um sich zeilenweise zu bewegen,
oder b und Leertaste ausprobieren, um eine ganze
Seite vor- und zurückzuspringen. Um nach einem Zeichen oder Wort in den
man-Seiten zu suchen, verwenden Sie /, gefolgt
von dem Zeichen oder Wort, das Sie suchen. Manchmal führt eine Suche zu
mehreren Treffern. In diesem Fall können Sie zwischen den Treffern mit
N (vorwärts) und Shift+N (rückwärts)
wechseln.
Um die man Seiten zu beenden, drücken
Sie q.
Manual pages on the web
Natürlich gibt es noch eine dritte Möglichkeit, auf die Hilfe für
Befehle zuzugreifen: die Suche im Internet über Ihren Webbrowser. Wenn
Sie die Internetsuche verwenden, hilft es, den Ausdruck
unix man page in Ihre Suchanfrage aufzunehmen, um relevante
Ergebnisse zu finden.
GNU bietet Links zu seinen Handbüchern, einschließlich der core GNU utilities, die viele in dieser Lektion vorgestellte Befehle abdeckt.
Weitere ls-Optionen
erforschen
Sie können auch zwei Optionen gleichzeitig verwenden. Was bewirkt der
Befehl ls, wenn er mit der Option -l verwendet
wird? Was ist, wenn Sie sowohl die Option -l als auch die
Option -h verwenden?
Ein Teil der Ausgabe bezieht sich auf Eigenschaften, die wir in dieser Lektion nicht behandeln (z.B. Dateiberechtigungen und Besitzverhältnisse), aber der Rest sollte trotzdem nützlich sein.
Die Option -l bewirkt, dass ls ein
llanges Listenformat verwendet, das nicht nur die
Datei-/Verzeichnisnamen, sondern auch zusätzliche Informationen wie die
Dateigröße und den Zeitpunkt der letzten Änderung anzeigt. Wenn Sie
sowohl die Option -h als auch die Option -l
verwenden, macht dies die Dateigröße ‘hmenschlich
lesbar’, d.h. es wird etwas wie 5.3K statt
5369 angezeigt.
Auflistung in umgekehrter chronologischer Reihenfolge
Standardmäßig listet ls den Inhalt eines Verzeichnisses
in alphabetischer Reihenfolge nach Namen auf. Der Befehl
ls -t listet die Einträge nicht alphabetisch, sondern nach
dem Zeitpunkt der letzten Änderung auf. Der Befehl ls -r
listet den Inhalt eines Verzeichnisses in umgekehrter Reihenfolge auf.
Welche Datei wird zuletzt angezeigt, wenn Sie die Optionen
-t und -r kombinieren? Hinweis: Möglicherweise
müssen Sie die Option -l verwenden, um das Datum der
letzten Änderung zu sehen.
Die zuletzt geänderte Datei wird zuletzt aufgelistet, wenn
-rt verwendet wird. Dies kann sehr nützlich sein, um die
letzten Bearbeitungen zu finden oder um zu überprüfen, ob eine neue
Ausgabedatei geschrieben wurde.
Andere Verzeichnisse erforschen
Wir können ls nicht nur für das aktuelle
Arbeitsverzeichnis verwenden, sondern auch, um den Inhalt eines anderen
Verzeichnisses aufzulisten. Schauen wir uns unser
Desktop-Verzeichnis an, indem wir
ls -F Desktop ausführen, d.h. den Befehl ls
mit der Option -F und dem
[Argument][Argumente] Desktop. Das
Argument Desktop sagt ls, dass wir eine
Auflistung von etwas anderem als unserem aktuellen Arbeitsverzeichnis
wollen:
AUSGABE
shell-lesson-data/
Beachten Sie, dass dieser Befehl einen Fehler zurückgibt, wenn ein
Verzeichnis namens Desktop in Ihrem aktuellen
Arbeitsverzeichnis nicht existiert. Normalerweise existiert ein
Desktop-Verzeichnis in Ihrem Home-Verzeichnis, von dem wir
annehmen, dass es das aktuelle Arbeitsverzeichnis Ihrer Bash-Shell
ist.
Ihre Ausgabe sollte eine Liste aller Dateien und Unterverzeichnisse
in Ihrem Desktop-Verzeichnis sein, einschließlich des
shell-lesson-data-Verzeichnisses, das Sie im [Setup für
diese Lektion] (../learners/setup.md) heruntergeladen haben. (Auf den
meisten Systemen wird der Inhalt des Verzeichnisses Desktop
in der Shell als Symbole in einer grafischen Benutzeroberfläche hinter
allen offenen Fenstern angezeigt. Prüfen Sie, ob dies bei Ihnen der Fall
ist.)
Die hierarchische Organisation von Dingen hilft uns, den Überblick über unsere Arbeit zu behalten. Es ist zwar möglich, Hunderte von Dateien in unserem Home-Verzeichnis abzulegen, so wie es möglich ist, Hunderte von gedruckten Papieren auf unserem Schreibtisch zu stapeln, aber es ist viel einfacher, Dinge zu finden, wenn sie in sinnvoll benannten Unterverzeichnissen organisiert sind.
Jetzt, da wir wissen, dass sich das Verzeichnis
shell-lesson-data in unserem Desktop-Verzeichnis befindet,
können wir zwei Dinge tun.
Zunächst können wir mit der gleichen Strategie wie zuvor seinen
Inhalt betrachten, indem wir einen Verzeichnisnamen an ls
übergeben:
AUSGABE
exercise-data/ north-pacific-gyre/
Zweitens können wir unseren Standort in ein anderes Verzeichnis ändern, so dass wir uns nicht mehr in unserem Homeverzeichnis befinden.
Der Befehl zum Wechseln des Verzeichnisses lautet cd,
gefolgt von einem Verzeichnisnamen, um das Arbeitsverzeichnis zu
wechseln.cd steht für “Verzeichnis wechseln”, was ein wenig
irreführend ist. Der Befehl wechselt nicht das Verzeichnis, sondern das
aktuelle Arbeitsverzeichnis der Shell. Mit anderen Worten, er ändert die
Einstellungen der Shell, in welchem Verzeichnis wir uns befinden. Der
Befehl cd ist vergleichbar mit einem Doppelklick auf einen
Ordner in einer grafischen Oberfläche, um in diesen Ordner zu
gelangen.
Nehmen wir an, wir wollen in das Verzeichnis
exercise-data wechseln, das wir oben gesehen haben. Wir
können die folgende Reihe von Befehlen verwenden, um dorthin zu
gelangen:
Diese Befehle verschieben uns von unserem Home-Verzeichnis in unser
Desktop-Verzeichnis, dann in das Verzeichnis
shell-lesson-data und dann in das Verzeichnis
exercise-data. Sie werden feststellen, dass cd
nichts ausgibt. Das ist normal. Viele Shell-Befehle geben bei
erfolgreicher Ausführung nichts auf dem Bildschirm aus. Wenn wir aber
pwd danach ausführen, können wir sehen, dass wir jetzt in
/Users/nelle/Desktop/shell-lesson-data/exercise-data
sind.
Wenn wir jetzt ls -F ohne Argumente ausführen, listet es
den Inhalt von
/Users/nelle/Desktop/shell-lesson-data/exercise-data auf,
weil wir uns jetzt dort befinden:
AUSGABE
/Users/nelle/Desktop/shell-lesson-data/exercise-data
AUSGABE
alkanes/ animal-counts/ creatures/ numbers.txt writing/
Wir wissen jetzt, wie wir im Verzeichnisbaum nach unten gehen (d.h. wie wir in ein Unterverzeichnis gehen), aber wie gehen wir nach oben (d.h. wie verlassen wir ein Verzeichnis und gehen in sein übergeordnetes Verzeichnis)? Wir könnten das Folgende versuchen:
FEHLER
-bash: cd: shell-lesson-data: No such file or directory
Aber wir bekommen einen Fehler! Woran liegt das?
Mit unseren bisherigen Methoden kann cd nur
Unterverzeichnisse innerhalb deines aktuellen Verzeichnisses sehen. Es
gibt verschiedene Möglichkeiten, Verzeichnisse oberhalb Ihres aktuellen
Standorts zu sehen; wir beginnen mit der einfachsten.
Es gibt eine Abkürzung in der Shell, um eine Verzeichnisebene höher zu gehen. Es funktioniert wie folgt:
.. ist ein spezieller Verzeichnisname, der “das
Verzeichnis, das dieses enthält” bedeutet, oder einfacher ausgedrückt,
das Elternteil des aktuellen Verzeichnisses.
Sicherlich, wenn wir pwd nach cd .. ausführen,
sind wir wieder in
/Users/nelle/Desktop/shell-lesson-data:
AUSGABE
/Users/nelle/Desktop/shell-lesson-data
Das spezielle Verzeichnis .. wird normalerweise nicht
angezeigt, wenn wir ls ausführen. Wenn wir es anzeigen
wollen, können wir die Option -a zu ls -F
hinzufügen:
AUSGABE
./ ../ exercise-data/ north-pacific-gyre/
-a steht für ‘show all’ (einschließlich versteckter
Dateien); es zwingt ls dazu, uns Datei- und
Verzeichnisnamen zu zeigen, die mit . beginnen, wie z.B.
.. (was sich, wenn wir in /Users/nelle sind,
auf das Verzeichnis /Users bezieht). Wie Sie sehen können,
zeigt es auch ein anderes spezielles Verzeichnis an, das einfach
. heißt, was “das aktuelle Arbeitsverzeichnis” bedeutet. Es
mag überflüssig erscheinen, einen Namen dafür zu haben, aber wir werden
bald einige Anwendungen dafür sehen.
Beachten Sie, dass in den meisten Kommandozeilen-Tools mehrere
Optionen mit einem einzigen - und ohne Leerzeichen zwischen
den Optionen kombiniert werden können; ls -F -a ist
äquivalent zu ls -Fa.
Andere versteckte Dateien
Zusätzlich zu den versteckten Verzeichnissen .. und
. sehen Sie möglicherweise auch eine Datei namens
.bash_profile. Diese Datei enthält normalerweise
Einstellungen für die Shell-Konfiguration. Sie können auch andere
Dateien und Verzeichnisse sehen, die mit . beginnen. Dies
sind normalerweise Dateien und Verzeichnisse, die zur Konfiguration
verschiedener Programme auf Ihrem Computer verwendet werden. Das Präfix
. wird verwendet, um zu verhindern, dass diese
Konfigurationsdateien das Terminal überladen, wenn ein Standardbefehl
ls verwendet wird.
Diese drei Befehle sind die grundlegenden Befehle zum Navigieren im
Dateisystem Ihres Computers: pwd, ls, und
cd. Lassen Sie uns einige Variationen dieser Befehle
untersuchen. Was passiert, wenn Sie cd allein eingeben,
ohne ein Verzeichnis anzugeben?
Wie kann man überprüfen, was passiert ist? pwd gibt uns
die Antwort!
AUSGABE
/Users/nelle
Es hat sich herausgestellt, dass cd ohne ein Argument
Sie zu Ihrem Homeverzeichnis zurückbringt, was großartig ist, wenn Sie
sich in Ihrem eigenen Dateisystem verirrt haben.
Versuchen wir, zu dem Verzeichnis exercise-data von
vorhin zurückzukehren. Letztes Mal haben wir drei Befehle benutzt, aber
wir können die Liste der Verzeichnisse, die wir nach
exercise-data verschieben wollen, in einem Schritt
zusammenstellen:
Überprüfen Sie, ob wir an den richtigen Ort umgezogen sind, indem Sie
pwd und ls -F ausführen.
Wenn wir vom Datenverzeichnis eine Ebene nach oben gehen wollen,
können wir cd .. verwenden. Es gibt aber auch eine andere
Möglichkeit, in ein beliebiges Verzeichnis zu wechseln, unabhängig
davon, wo Sie sich gerade befinden.
Bislang haben wir bei der Angabe von Verzeichnisnamen oder sogar
eines Verzeichnispfades (wie oben) relative Pfade
verwendet. Wenn Sie einen relativen Pfad mit einem Befehl wie
ls oder cd verwenden, wird versucht, diesen
Ort von der Stelle aus zu finden, an der wir uns befinden, und nicht von
der Root des Dateisystems.
Es ist jedoch möglich, den absoluten Pfad zu einem Verzeichnis anzugeben, indem man den gesamten Pfad vom Stammverzeichnis aus einbezieht, was durch einen führenden Schrägstrich angezeigt wird. Der führende Schrägstrich sagt dem Computer, dass er den Pfad vom Stammverzeichnis des Dateisystems aus verfolgen soll, so dass er sich immer auf genau ein Verzeichnis bezieht, egal wo wir uns befinden, wenn wir den Befehl ausführen.
So können wir von überall im Dateisystem in unser
shell-lesson-data-Verzeichnis wechseln (auch innerhalb von
exercise-data). Um den absoluten Pfad zu finden, den wir
suchen, können wir pwd verwenden und dann das Stück
extrahieren, das wir nach shell-lesson-data verschieben
wollen.
AUSGABE
/Users/nelle/Desktop/shell-lesson-data/exercise-data
Führen Sie pwd und ls -F aus, um
sicherzustellen, dass wir uns in dem Verzeichnis befinden, das wir
erwarten.
Zwei weitere Abkürzungen
Die Shell interpretiert eine Tilde (~) am Anfang eines
Pfades als “das Homeverzeichnis des aktuellen Benutzers”. Wenn zum
Beispiel das Homeverzeichnis von Nelle /Users/nelle ist,
dann ist ~/data äquivalent zu
/Users/nelle/data. Das funktioniert nur, wenn es das erste
Zeichen im Pfad ist; here/there/~/elsewhere ist
nicht here/there/Users/nelle/elsewhere.
Eine weitere Abkürzung ist das Zeichen -
(Bindestrich).cd übersetzt- in das
vorherige Verzeichnis, in dem ich mich befand, was schneller ist,
als sich an den vollständigen Pfad zu erinnern und ihn dann einzugeben.
Dies ist ein sehr effizienter Weg, um zwischen zwei
Verzeichnissen hin und her zu wechseln – d.h. wenn Sie
cd - zweimal ausführen, landen Sie wieder im
Ausgangsverzeichnis.
Der Unterschied zwischen cd .. und cd -
ist, dass ersteres Sie nach oben bringt, während letzteres Sie
zurück bringt.
Versuchen Sie es! Navigieren Sie zuerst zu
~/Desktop/shell-lesson-data (Sie sollten bereits dort
sein).
Dann cd in das exercise-data/creatures
Verzeichnis
Wenn Sie nun folgendes ausführen
Sie werden sehen, dass Sie sich wieder in
~/Desktop/shell-lesson-data befinden. Führen Sie
cd - erneut aus und Sie befinden sich wieder in
~/Desktop/shell-lesson-data/exercise-data/creatures
Absolute vs. Relative Pfade
Welchen der folgenden Befehle könnte Nelle ausgehend von
/Users/nelle/data verwenden, um zu ihrem Homeverzeichnis zu
navigieren, das /Users/nelle ist?
cd .cd /cd /home/nellecd ../..cd ~cd homecd ~/data/..cdcd ..
- Nein:
.steht für das aktuelle Verzeichnis. - Nein:
/steht für das Stammverzeichnis. - Nein: Nelle’s Homeverzeichnis ist
/Users/nelle. - Nein: Dieser Befehl geht zwei Ebenen nach oben, d.h. er endet mit
/Users. - Ja:
~steht für das Homeverzeichnis des Benutzers, in diesem Fall/Users/nelle. - Nein: Dieser Befehl würde in ein Verzeichnis
homeim aktuellen Verzeichnis navigieren, wenn es existiert. - Ja: unnötig kompliziert, aber korrekt.
- Ja: Abkürzung, um zum Homeverzeichnis des Benutzers zurückzukehren.
- Ja: geht eine Ebene höher.
Relative Pfadauflösung
Wenn pwd /Users/thing anzeigt, was zeigt
dann ls -F ../backup im untenstehenden Dateisystemdiagramm
an?
../backup: No such file or directory2012-12-01 2013-01-08 2013-01-272012-12-01/ 2013-01-08/ 2013-01-27/original/ pnas_final/ pnas_sub/
{alt=“Ein Verzeichnisbaum
unterhalb des Users-Verzeichnisses, in dem”/Users” die Verzeichnisse
“backup” und “thing” enthält; “/Users/backup” enthält “original”,
“pnas_final” und “pnas_sub”; “/Users/thing” enthält “backup”; und
“/Users/thing/backup” enthält “2012-12-01”, “2013-01-08” und
“2013-01-27”“}
- Nein: Es gibt ein Verzeichnis
backupin/Users. - Nein: das ist der Inhalt von
Users/thing/backup, aber mit..haben wir nach einer Ebene weiter oben gefragt. - Nein: siehe vorherige Erklärung.
- Ja:
../backup/verweist auf/Users/backup/.
Einsichten in ls
Wenn pwd /Users/backup anzeigt und
-r ls anweist, die Dinge in umgekehrter
Reihenfolge anzuzeigen, welche(r) Befehl(e) führt/führen dann zu
folgender Ausgabe?
AUSGABE
pnas_sub/ pnas_final/ original/
{alt=“Ein Verzeichnisbaum
unterhalb des Users-Verzeichnisses, in dem”/Users” die Verzeichnisse
“backup” und “thing” enthält; “/Users/backup” enthält “original”,
“pnas_final” und “pnas_sub”; “/Users/thing” enthält “backup”; und
“/Users/thing/backup” enthält “2012-12-01”, “2013-01-08” und
“2013-01-27”“}
ls pwdls -r -Fls -r -F /Users/backup
- Nein:
pwdist nicht der Name eines Verzeichnisses. - Ja:
lsohne Verzeichnisargument listet Dateien und Verzeichnisse im aktuellen Verzeichnis auf. - Ja: verwendet explizit den absoluten Pfad.
Allgemeine Syntax eines Shell-Befehls
Wir haben nun Befehle, Optionen und Argumente kennengelernt, aber es ist vielleicht sinnvoll, einige Begriffe zu formalisieren.
Betrachten Sie den folgenden Befehl als ein allgemeines Beispiel für einen Befehl, den wir in seine Bestandteile zerlegen werden:
ls ist der Befehl, mit einer
Option -F und einem
Argument /. Wir haben bereits Optionen
kennengelernt, die entweder mit einem einzelnen Bindestrich beginnen
(-), bekannt als kurze Optionen, oder mit
zwei Bindestrichen (--), bekannt als lange
Optionen. [Optionen] ändern das Verhalten eines Befehls und
Argumente] sagen dem Befehl, womit er arbeiten soll (z.B. Dateien und
Verzeichnisse). Manchmal werden Optionen und Argumente auch als
Parameter bezeichnet. Ein Befehl kann mit mehr als
einer Option und mehr als einem Argument aufgerufen werden, aber ein
Befehl benötigt nicht immer ein Argument oder eine Option.
Manchmal sieht man, dass Optionen als Schalter oder Flags bezeichnet werden, besonders bei Optionen, die kein Argument benötigen. In dieser Lektion werden wir bei dem Begriff Option bleiben.
Jeder Teil ist durch Leerzeichen getrennt. Wenn Sie das Leerzeichen
zwischen ls und -F weglassen, wird die Shell
nach einem Befehl namens ls-F suchen, den es nicht gibt.
Auch die Großschreibung kann wichtig sein. Zum Beispiel zeigt
ls -s die Größe von Dateien und Verzeichnissen neben den
Namen an, während ls -S die Dateien und Verzeichnisse nach
Größe sortiert, wie unten gezeigt:
AUSGABE
total 28
4 animal-counts 4 creatures 12 numbers.txt 4 alkanes 4 writing
Beachten Sie, dass die von ls -s zurückgegebenen Größen
in Blöcken angegeben sind. Da diese für verschiedene
Betriebssysteme unterschiedlich definiert sind, erhalten Sie
möglicherweise nicht die gleichen Zahlen wie im Beispiel.
AUSGABE
animal-counts creatures alkanes writing numbers.txt
Wenn man das alles zusammennimmt, gibt uns der obige Befehl
ls -F / eine Liste der Dateien und Verzeichnisse im
Stammverzeichnis /. Ein Beispiel für die Ausgabe, die Sie
mit dem obigen Befehl erhalten könnten, finden Sie unten:
AUSGABE
Applications/ System/
Library/ Users/
Network/ Volumes/
Nelle’s Pipeline: Organisieren von Dateien
Mit diesem Wissen über Dateien und Verzeichnisse ist Nelle bereit, die Dateien zu organisieren, die die Protein-Assay-Maschine erstellen wird.
Sie erstellt ein Verzeichnis mit dem Namen
north-pacific-gyre (um sich daran zu erinnern, woher die
Daten stammen), das die Datendateien von der Testmaschine und ihre
Datenverarbeitungsskripte enthalten wird.
Jede ihrer physischen Proben ist gemäß der Konvention ihres Labors
mit einer eindeutigen zehnstelligen ID gekennzeichnet, z. B.
“NENE01729A”. Diese ID hat sie in ihrem Entnahmeprotokoll verwendet, um
den Ort, die Zeit, die Tiefe und andere Merkmale der Probe
aufzuzeichnen, daher beschließt sie, sie im Dateinamen jeder Datendatei
zu verwenden. Da die Ausgabe des Prüfgeräts im Klartext erfolgt, nennt
sie ihre Dateien NENE01729A.txt,
NENE01812A.txt usw. Alle 1520 Dateien werden im selben
Verzeichnis gespeichert.
Jetzt kann Nelle in ihrem aktuellen Verzeichnis
shell-lesson-data sehen, welche Dateien sie hat, indem sie
den Befehl benutzt:
Dieser Befehl ist eine Menge zu tippen, aber sie kann die Shell die meiste Arbeit durch die sogenannte Tab-Vervollständigung erledigen lassen. Wenn sie tippt:
und drückt dann Tab (die Tabulator-Taste auf ihrer Tastatur), vervollständigt die Shell automatisch den Verzeichnisnamen für sie:
Erneutes Drücken von Tab bringt nichts, da es mehrere Möglichkeiten gibt; zweimaliges Drücken von Tab führt zu einer Liste aller Dateien.
Wenn Nelle dann G drückt und dann wieder Tab drückt, wird die Shell ‘goo’ anhängen, da alle Dateien, die mit ‘g’ beginnen, die ersten drei Zeichen ‘goo’ gemeinsam haben.
Um alle diese Dateien zu sehen, kann sie Tab noch zweimal drücken.
Dies wird Tab-Vervollständigung genannt, und wir werden es im weiteren Verlauf in vielen anderen Tools sehen.
- Das Dateisystem ist für die Verwaltung von Informationen auf der Festplatte zuständig.
- Informationen werden in Dateien gespeichert, die wiederum in Verzeichnissen (Ordnern) abgelegt sind.
- Verzeichnisse können auch andere Verzeichnisse speichern, die dann einen Verzeichnisbaum bilden.
-
pwdgibt das aktuelle Arbeitsverzeichnis des Benutzers aus. -
ls [path]gibt eine Auflistung einer bestimmten Datei oder eines bestimmten Verzeichnisses aus;lsallein listet das aktuelle Arbeitsverzeichnis auf. -
cd [path]ändert das aktuelle Arbeitsverzeichnis. - Die meisten Befehle nehmen Optionen an, die mit einem einzelnen
-beginnen. - Verzeichnisnamen in einem Pfad werden unter Unix mit
/getrennt, unter Windows jedoch mit\. -
/allein ist das Stammverzeichnis des gesamten Dateisystems. - Ein absoluter Pfad gibt einen Ort an, der von der Root des Dateisystems ausgeht.
- Ein relativer Pfad gibt einen Ort an, der vom aktuellen Ort ausgeht.
-
.allein bedeutet ‘das aktuelle Verzeichnis’;..bedeutet ‘das Verzeichnis über dem aktuellen’.
Content from Arbeiten mit Dateien und Verzeichnissen
Zuletzt aktualisiert am 2025-10-23 | Diese Seite bearbeiten
Übersicht
Fragen
- Wie kann ich Dateien und Verzeichnisse erstellen, kopieren und löschen?
- Wie kann ich Dateien bearbeiten?
Ziele
- Löschen, Kopieren und Verschieben von angegebenen Dateien und/oder Verzeichnissen.
- Erstellen Sie Dateien in dieser Hierarchie mit einem Editor oder durch Kopieren und Umbenennen vorhandener Dateien.
- Erstellen Sie eine Verzeichnishierarchie, die einem vorgegebenen Diagramm entspricht.
Erstellen von Verzeichnissen
Wir wissen jetzt, wie wir Dateien und Verzeichnisse erkunden können, aber wie erstellen wir sie überhaupt?
In dieser Folge lernen wir das Erstellen und Verschieben von Dateien
und Verzeichnissen am Beispiel des Verzeichnisses
exercise-data/writing.
Erster Schritt: sehen, wo wir sind und was wir bereits haben
Wir sollten uns immer noch im Verzeichnis
shell-lesson-data auf dem Desktop befinden, was wir mit
überprüfen können:
AUSGABE
/Users/nelle/Desktop/shell-lesson-data
Als nächstes werden wir in das Verzeichnis
exercise-data/writing wechseln und sehen, was es
enthält:
AUSGABE
haiku.txt LittleWomen.txt
Erstellen Sie ein Verzeichnis
Erstellen wir ein neues Verzeichnis namens thesis mit
dem Befehl mkdir thesis (der keine Ausgabe hat):
Wie der Name schon vermuten lässt, bedeutet mkdir ‘make
directory’ (‘Verzeichnis erstellen’). Da thesis ein
relativer Pfad ist (d.h. keinen führenden Schrägstrich hat, wie
/what/ever/thesis), wird das neue Verzeichnis im aktuellen
Arbeitsverzeichnis erstellt:
AUSGABE
haiku.txt LittleWomen.txt thesis/
Da wir das Verzeichnis thesis gerade erst erstellt
haben, befindet sich darin noch nichts:
Beachten Sie, dass mkdir nicht darauf beschränkt ist,
einzelne Verzeichnisse auf einmal zu erstellen. Die Option
-p erlaubt mkdir, ein Verzeichnis mit
verschachtelten Unterverzeichnissen in einem einzigen Vorgang zu
erstellen:
Die Option -R zum ls Befehl listet alle
verschachtelten Unterverzeichnisse innerhalb eines Verzeichnisses auf.
Lassen Sie uns ls -FR verwenden, um rekursiv die neue
Verzeichnishierarchie aufzulisten, die wir gerade im Verzeichnis
project erstellt haben:
AUSGABE
../project/:
data/ results/
../project/data:
../project/results:
Zwei Möglichkeiten, das Gleiche zu tun
Die Verwendung der Shell zur Erstellung eines Verzeichnisses
unterscheidet sich nicht von der Verwendung eines Datei-Explorers. Wenn
Sie das aktuelle Verzeichnis mit dem grafischen Dateiexplorer Ihres
Betriebssystems öffnen, wird das Verzeichnis thesis auch
dort erscheinen. Während die Shell und der Dateiexplorer zwei
verschiedene Wege sind, mit den Dateien zu interagieren, sind die
Dateien und Verzeichnisse selbst die gleichen.
Gute Namen für Dateien und Verzeichnisse
Komplizierte Namen von Dateien und Verzeichnissen können Ihnen das Leben schwer machen, wenn Sie auf der Kommandozeile arbeiten. Hier geben wir Ihnen ein paar nützliche Tipps für die Namen Ihrer Dateien und Verzeichnisse.
- Verwenden Sie keine Leerzeichen.
Leerzeichen können einen Namen aussagekräftiger machen, aber da
Leerzeichen verwendet werden, um Argumente auf der Kommandozeile zu
trennen, ist es besser, sie in Namen von Dateien und Verzeichnissen zu
vermeiden. Sie können stattdessen - oder _
verwenden (z.B. north-pacific-gyre/ anstelle von
north pacific gyre/). Um dies zu testen, versuchen Sie
mkdir north pacific gyre einzugeben und sehen Sie, welches
Verzeichnis (oder Verzeichnisse!) erstellt wird, wenn Sie mit
ls -F prüfen.
- Beginnen Sie den Namen nicht mit
-(Bindestrich).
Befehle behandeln Namen, die mit - beginnen, als
Optionen.
- Bleiben Sie bei Buchstaben, Zahlen,
.(Punkt),-(Bindestrich) und_(Unterstrich).
Viele andere Zeichen haben in der Kommandozeile eine besondere Bedeutung. Wir werden in dieser Lektion einige davon kennenlernen. Es gibt Sonderzeichen, die dazu führen können, dass Ihr Befehl nicht wie erwartet funktioniert, und die sogar zu Datenverlust führen können.
Wenn Sie auf Namen von Dateien oder Verzeichnissen verweisen müssen,
die Leerzeichen oder andere Sonderzeichen enthalten, sollten Sie den
Namen in einfache Anführungszeichen
einschließen ('').
Erstellen einer Textdatei
Wechseln wir unser Arbeitsverzeichnis mit cd in
thesis und erstellen mit dem Texteditor Nano eine Datei
namens draft.txt:
Welcher Editor?
Wenn wir sagen, ‘nano ist ein Texteditor’, dann meinen
wir wirklich ‘Text’. Er kann nur mit einfachen Zeichendaten arbeiten,
nicht mit Tabellen, Bildern oder anderen menschenfreundlichen Medien.
Wir verwenden ihn in den Beispielen, weil er einer der am wenigsten
komplexen Texteditoren ist. Aufgrund dieser Eigenschaft ist er jedoch
möglicherweise nicht leistungsfähig oder flexibel genug für die Arbeit,
die Sie nach diesem Workshop erledigen müssen. Auf Unix-Systemen (wie
Linux und macOS) verwenden viele Programmierer Emacs oder Vim (die beide mehr Zeit zum Erlernen
benötigen) oder einen grafischen Editor wie Gedit oder VScode. Unter Windows können
Sie auch Notepad++
verwenden. Windows hat auch einen eingebauten Editor namens
notepad, der von der Befehlszeile aus auf die gleiche Weise
wie nano für die Zwecke dieser Lektion ausgeführt werden
kann.
Unabhängig davon, welchen Editor Sie verwenden, müssen Sie wissen, wo er Dateien sucht und speichert. Wenn Sie ihn von der Shell aus starten, wird er (wahrscheinlich) Ihr aktuelles Arbeitsverzeichnis als Standardverzeichnis verwenden. Wenn Sie das Startmenü Ihres Computers verwenden, speichert er die Dateien möglicherweise stattdessen in Ihrem Desktop- oder Dokumentenverzeichnis. Sie können dies ändern, indem Sie beim ersten Mal, wenn Sie “Speichern unter…” wählen, in ein anderes Verzeichnis wechseln
Geben wir ein paar Zeilen Text ein.

Wenn wir mit unserem Text zufrieden sind, können wir
Strg+O drücken (drücken Sie die Strg
oder Steuerung Taste und, während Sie sie gedrückt halten,
drücken Sie die O Taste), um unsere Daten auf die Festplatte
zu schreiben. Wir werden aufgefordert, einen Namen für die Datei
anzugeben, die unseren Text enthalten soll. Drücken Sie
Return, um die vorgeschlagene Vorgabe draft.txt
zu übernehmen.
Sobald unsere Datei gespeichert ist, können wir Strg+X verwenden, um den Editor zu verlassen und zur Shell zurückzukehren.
Steuerung, Strg, oder ^ Taste
Die Steuerungstaste wird auch als ‘Strg’-Taste bezeichnet. Es gibt verschiedene Möglichkeiten, die Verwendung der Steuerungstaste zu beschreiben. Zum Beispiel können Sie eine Anweisung sehen, die Steuertaste zu drücken und, während Sie sie gedrückt halten, die X-Taste zu drücken, die wie folgt beschrieben wird:
Strg-XStrg+XStrg-XStrg+X^XC-x
In nano sehen Sie am unteren Rand des Bildschirms
^G Get Help ^O WriteOut. Das bedeutet, dass du
Control-G benutzen kannst, um Hilfe zu bekommen und
Control-O, um deine Datei zu speichern.
nano hinterlässt nach dem Beenden keine Ausgabe auf dem
Bildschirm, aber ls zeigt nun, dass wir eine Datei namens
draft.txt erstellt haben:
AUSGABE
draft.txt
Dateien auf eine andere Weise erstellen
Wir haben gesehen, wie man Textdateien mit dem Editor
nano erstellt. Versuchen Sie nun den folgenden Befehl:
Was hat der Befehl
touchbewirkt? Wenn Sie sich Ihr aktuelles Verzeichnis mit dem GUI-Dateiexplorer ansehen, wird die Datei dann angezeigt?Benutze
ls -l, um die Dateien zu untersuchen. Wie groß istmy_file.txt?Wann würden Sie eine Datei auf diese Weise erstellen wollen?
Der Befehl
toucherzeugt eine neue Datei namensmy_file.txtin Ihrem aktuellen Verzeichnis. Sie können diese neu erzeugte Datei beobachten, indem Sielsan der Eingabeaufforderung eingeben. die Dateimy_file.txtkann auch in Ihrem GUI-Dateiexplorer angezeigt werden.Wenn Sie die Datei mit
ls -luntersuchen, beachten Sie, dass die Größe vonmy_file.txt0 Bytes beträgt. Mit anderen Worten, sie enthält keine Daten. Wenn Siemy_file.txtmit Ihrem Texteditor öffnen, ist sie leer.Einige Programme erzeugen nicht selbst Ausgabedateien, sondern setzen voraus, dass bereits leere Dateien erzeugt wurden. Wenn das Programm ausgeführt wird, sucht es nach einer vorhandenen Datei, um sie mit seiner Ausgabe zu füllen. Mit dem Befehl touch können Sie auf effiziente Weise eine leere Textdatei erzeugen, die von solchen Programmen verwendet werden kann.
Dateien auf eine andere Weise erstellen (continued)
What’s In A Name?
Sie haben vielleicht bemerkt, dass alle Dateien von Nelle
“irgendetwas dot irgendetwas” heißen, und in diesem Teil der Lektion
haben wir immer die Erweiterung .txt verwendet. Dies ist
nur eine Konvention; wir können eine Datei mythesis oder
fast alles andere nennen, was wir wollen. Die meisten Leute verwenden
jedoch meist zweiteilige Namen, um ihnen (und ihren Programmen) zu
helfen, verschiedene Arten von Dateien zu unterscheiden. Der zweite Teil
eines solchen Namens wird Dateinamenerweiterung genannt
und gibt an, welche Art von Daten die Datei enthält: .txt
signalisiert eine einfache Textdatei, .pdf weist auf ein
PDF-Dokument hin, .cfg ist eine Konfigurationsdatei mit
Parametern für ein Programm oder ein anderes, .png ist ein
PNG-Bild, und so weiter.
Dies ist nur eine Konvention, wenn auch eine wichtige. Dateien enthalten lediglich Bytes; es liegt an uns und unseren Programmen, diese Bytes gemäß den Regeln für einfache Textdateien, PDF-Dokumente, Konfigurationsdateien, Bilder usw. zu interpretieren.
Ein PNG-Bild eines Wals als whale.mp3 zu benennen,
verwandelt es nicht irgendwie auf magische Weise in eine Aufnahme von
Walgesang, obwohl es möglicherweise das Betriebssystem
veranlasst, die Datei mit einem Musikabspielprogramm zu assoziieren. In
diesem Fall, wenn jemand in einem Dateiexplorer-Programm auf
whale.mp3 doppelklickt, wird der Musik-Player automatisch
(und fälschlicherweise) versuchen, die Datei whale.mp3 zu
öffnen.
Dateien und Verzeichnisse verschieben
Rückkehr in das Verzeichnis
shell-lesson-data/exercise-data/writing,
In unserem thesis Verzeichnis haben wir eine Datei
draft.txt, was kein besonders informativer Name ist, also
ändern wir den Namen der Datei mit mv, was kurz für ‘move’
(‘verschieben’) ist:
Das erste Argument gibt an, was wir verschieben, während das zweite
angibt, wohin es gehen soll. In diesem Fall verschieben wir
thesis/draft.txt nach thesis/quotes.txt, was
den gleichen Effekt hat wie das Umbenennen der Datei. Sicherlich zeigt
uns ls, dass thesis nun eine Datei namens
quotes.txt enthält:
AUSGABE
quotes.txt
Man muss vorsichtig sein, wenn man den Namen der Zieldatei angibt, da
mv stillschweigend jede existierende Datei mit demselben
Namen überschreibt, was zu Datenverlust führen kann. Standardmäßig wird
mv vor dem Überschreiben von Dateien nicht nach einer
Bestätigung fragen. Eine zusätzliche Option, mv -i (oder
mv --interactive), veranlasst mv jedoch, eine
solche Bestätigung zu verlangen.
Beachten Sie, dass mv auch bei Verzeichnissen
funktioniert.
Lass uns quotes.txt in das aktuelle Arbeitsverzeichnis
verschieben. Wir verwenden wieder mv, aber dieses Mal geben
wir nur den Namen eines Verzeichnisses als zweites Argument an, um
mv mitzuteilen, dass wir den Dateinamen behalten, aber die
Datei an einen neuen Ort verschieben wollen. (Deshalb heißt der Befehl
‘move’.) In diesem Fall ist der Verzeichnisname, den wir verwenden, der
spezielle Verzeichnisname ., den wir bereits erwähnt
haben.
Der Effekt ist, dass die Datei von dem Verzeichnis, in dem sie sich
befand, in das aktuelle Arbeitsverzeichnis verschoben wird.
ls zeigt uns nun, dass thesis leer ist:
AUSGABE
$
Alternativ können wir bestätigen, dass die Datei
quotes.txt nicht mehr im Verzeichnis thesis
vorhanden ist, indem wir explizit versuchen, sie aufzulisten:
FEHLER
ls: cannot access 'thesis/quotes.txt': No such file or directory
ls mit einem Dateinamen oder Verzeichnis als Argument
listet nur die angeforderte Datei oder das Verzeichnis auf. Wenn die als
Argument angegebene Datei nicht existiert, gibt die Shell einen Fehler
zurück, wie wir oben gesehen haben. Wir können dies benutzen, um zu
sehen, dass quotes.txt jetzt in unserem aktuellen
Verzeichnis vorhanden ist:
AUSGABE
quotes.txt
Verschieben von Dateien in einen neuen Ordner
Nachdem sie die folgenden Befehle ausgeführt hat, stellt Jamie fest,
dass sie die Dateien sucrose.dat und
maltose.dat in den falschen Ordner gelegt hat. Die Dateien
hätten in den Ordner raw gelegt werden müssen.
BASH
$ ls -F
analyzed/ raw/
$ ls -F analyzed
fructose.dat glucose.dat maltose.dat sucrose.dat
$ cd analyzed
Füllen Sie die Felder aus, um diese Dateien in den Ordner
raw/ zu verschieben (d.h. in den Ordner, in den sie
vergessen hat, sie abzulegen)
Kopieren von Dateien und Verzeichnissen
Der Befehl cp funktioniert ähnlich wie mv,
nur dass er eine Datei kopiert, anstatt sie zu verschieben. Wir können
überprüfen, ob er das Richtige getan hat, indem wir ls mit
zwei Pfaden als Argumente verwenden — wie die meisten Unix-Befehle kann
ls mehrere Pfade auf einmal erhalten:
AUSGABE
quotes.txt thesis/quotations.txt
Wir können auch ein Verzeichnis und seinen gesamten Inhalt kopieren,
indem wir die Option recursive
-r verwenden, z.B. um ein Verzeichnis zu sichern:
Wir können das Ergebnis überprüfen, indem wir den Inhalt der beiden
Verzeichnisse thesis und thesis_backup
auflisten:
AUSGABE
thesis:
quotations.txt
thesis_backup:
quotations.txt
Es ist wichtig, das -r-Flag einzuschließen. Wenn Sie ein
Verzeichnis kopieren wollen und diese Option weglassen, werden Sie eine
Meldung sehen, dass das Verzeichnis weggelassen wurde, weil
-r not specified.
Umbenennen von Dateien
Angenommen, Sie haben in Ihrem aktuellen Verzeichnis eine Textdatei
erstellt, die eine Liste der statistischen Tests enthält, die Sie für
die Analyse Ihrer Daten benötigen, und sie statstics.txt
genannt
Nachdem Sie diese Datei erstellt und gespeichert haben, stellen Sie fest, dass Sie den Dateinamen falsch geschrieben haben! Sie möchten den Fehler korrigieren. Welchen der folgenden Befehle können Sie dazu verwenden?
cp statstics.txt statistics.txtmv statstics.txt statistics.txtmv statstics.txt .cp statstics.txt .
- Nein. Dies würde zwar eine Datei mit dem richtigen Namen erstellen, aber die falsch benannte Datei ist noch im Verzeichnis vorhanden und müsste gelöscht werden.
- Ja, das würde funktionieren, um die Datei umzubenennen.
- Nein, der Punkt(.) zeigt an, wohin die Datei verschoben werden soll, gibt aber keinen neuen Dateinamen an; identische Dateinamen können nicht erstellt werden.
- Nein, der Punkt(.) gibt an, wohin die Datei kopiert werden soll, liefert aber keinen neuen Dateinamen; identische Dateinamen können nicht erstellt werden.
Verschieben und Kopieren
Was ist die Ausgabe des abschließenden Befehls ls in der
unten gezeigten Reihenfolge?
AUSGABE
/Users/jamie/data
AUSGABE
proteins.dat
BASH
$ mkdir recombined
$ mv proteins.dat recombined/
$ cp recombined/proteins.dat ../proteins-saved.dat
$ ls
proteins-saved.dat recombinedrecombinedproteins.dat recombinedproteins-saved.dat
Wir beginnen im Verzeichnis /Users/jamie/data und
erstellen einen neuen Ordner namens recombined. Die zweite
Zeile verschiebt (mv) die Datei proteins.dat
in den neuen Ordner (recombined). Die dritte Zeile erstellt
eine Kopie der Datei, die wir gerade verschoben haben. Der knifflige
Teil hier ist, wohin die Datei kopiert wurde. Erinnern Sie sich, dass
.. “eine Ebene höher gehen” bedeutet, also befindet sich
die kopierte Datei jetzt in /Users/jamie. Beachten Sie,
dass .. in Bezug auf das aktuelle Arbeitsverzeichnis
interpretiert wird, nicht in Bezug auf den Ort der
kopierten Datei. Das einzige, was mit ls (in
/Users/jamie/data) angezeigt wird, ist also der neu
zusammengestellte Ordner.
- Nein, siehe Erklärung oben.
proteins-saved.datbefindet sich in/Users/jamie - Ja
- Nein, siehe Erklärung oben.
proteins.datbefindet sich in/Users/jamie/data/recombined - Nein, siehe Erklärung oben.
proteins-saved.datbefindet sich in/Users/jamie
Entfernen von Dateien und Verzeichnissen
Kehren wir zum Verzeichnis
shell-lesson-data/exercise-data/writing zurück und räumen
wir dieses Verzeichnis auf, indem wir die Datei quotes.txt
entfernen, die wir erstellt haben. Der Unix-Befehl, den wir dafür
verwenden, ist rm (kurz für ‘remove’):
Wir können bestätigen, dass die Datei mit ls
verschwunden ist:
FEHLER
ls: cannot access 'quotes.txt': No such file or directory
Deleting Is Forever
Die Unix-Shell hat keinen Papierkorb, aus dem wir gelöschte Dateien wiederherstellen können (obwohl die meisten grafischen Oberflächen von Unix dies tun). Wenn wir Dateien löschen, werden sie stattdessen aus dem Dateisystem entfernt, damit ihr Speicherplatz auf der Festplatte wiederverwendet werden kann. Es gibt zwar Tools zum Auffinden und Wiederherstellen gelöschter Dateien, aber es gibt keine Garantie, dass sie in jeder Situation funktionieren, da der Computer den Speicherplatz der Datei möglicherweise sofort wiederverwendet.
Sichere Verwendung von rm
Was passiert, wenn wir
rm -i thesis_backup/quotations.txt ausführen? Warum sollten
wir diesen Schutz haben, wenn wir rm verwenden?
AUSGABE
rm: remove regular file 'thesis_backup/quotations.txt'? y
Die Option -i fragt vor (jedem) Löschen nach (verwenden
Sie Y, um das Löschen zu bestätigen oder N, um die
Datei zu behalten). Die Unix-Shell hat keinen Mülleimer, so dass alle
gelöschten Dateien für immer verschwinden werden. Mit der Option
-i können wir überprüfen, dass wir nur die Dateien löschen,
die wir auch wirklich löschen wollen.
Wenn wir versuchen, das Verzeichnis thesis mit
rm thesis zu entfernen, erhalten wir eine
Fehlermeldung:
FEHLER
rm: cannot remove 'thesis': Is a directory
Das passiert, weil rm standardmäßig nur bei Dateien
funktioniert, nicht bei Verzeichnissen.
rm kann ein Verzeichnis mitsamt seinem Inhalt
entfernen, wenn wir die rekursive Option -r verwenden, und
es wird dies ohne jegliche Bestätigungsaufforderung tun:
Da es keine Moeglichkeit gibt, mit der Shell geloeschte Dateien
wiederherzustellen, sollte rm -r mit grosser
Vorsicht verwendet werden (man koennte die interaktive Option
rm -r -i hinzufuegen).
Operationen mit mehreren Dateien und Verzeichnissen
Oftmals muss man mehrere Dateien auf einmal kopieren oder verschieben. Dies kann durch die Angabe einer Liste einzelner Dateinamen oder durch die Angabe eines Namensmusters mit Wildcards geschehen. Wildcards sind Sonderzeichen, die verwendet werden können, um unbekannte Zeichen oder Zeichensätze bei der Navigation im Unix-Dateisystem darzustellen.
Kopieren mit mehreren Dateinamen
Für diese Übung können Sie die Befehle im Verzeichnis
shell-lesson-data/exercise-data testen.
Was macht cp im folgenden Beispiel, wenn mehrere
Dateinamen und ein Verzeichnisname angegeben werden?
Was macht cp im folgenden Beispiel, wenn drei oder mehr
Dateinamen angegeben werden?
AUSGABE
basilisk.dat minotaur.dat unicorn.dat
Wenn mehr als ein Dateiname gefolgt von einem Verzeichnisnamen
angegeben wird (d.h. das Zielverzeichnis muss das letzte Argument sein),
kopiert cp die Dateien in das genannte Verzeichnis.
Wenn drei Dateinamen angegeben werden, gibt cp einen
Fehler wie den folgenden aus, weil es einen Verzeichnisnamen als letztes
Argument erwartet.
FEHLER
cp: target 'basilisk.dat' is not a directory
Verwendung von Platzhaltern für den gleichzeitigen Zugriff auf mehrere Dateien
Wildcards
* ist eine Wildcard, die für null oder
mehr andere Zeichen steht. Betrachten wir das Verzeichnis
shell-lesson-data/exercise-data/alkanes: *.pdb
steht für ethane.pdb, propane.pdb und jede
Datei, die mit ‘.pdb’ endet. Auf der anderen Seite repräsentiert
p*.pdb nur pentane.pdb und
propane.pdb, weil das ‘p’ am Anfang nur Dateinamen
repräsentieren kann, die mit dem Buchstaben ‘p’ beginnen.
? ist auch ein Platzhalter, aber er steht für genau ein
Zeichen. So könnte ?ethane.pdb für methane.pdb
stehen, während *ethane.pdb sowohl für
ethane.pdb als auch für methane.pdb steht.
Wildcards können in Kombination miteinander verwendet werden. Zum
Beispiel gibt ???ane.pdb drei Zeichen an, gefolgt von
ane.pdb, was cubane.pdb ethane.pdb octane.pdb
ergibt.
Wenn die Shell einen Platzhalter sieht, expandiert sie diesen, um
eine Liste passender Dateinamen zu erstellen, bevor sie den
vorangehenden Befehl ausführt. Ausnahmsweise, wenn ein
Platzhalterausdruck mit keiner Datei übereinstimmt, übergibt die Bash
den Ausdruck als Argument an den Befehl, wie er ist. Wenn Sie
beispielsweise ls *.pdf im Verzeichnis alkanes
eingeben (das nur Dateien enthält, deren Namen auf .pdb
enden), erhalten Sie die Fehlermeldung, dass es keine Datei namens
*.pdf gibt. Im Allgemeinen sehen Befehle wie
wc und ls jedoch die Listen der Dateinamen,
die auf diese Ausdrücke passen, aber nicht die Platzhalter selbst. Es
ist die Shell, nicht die anderen Programme, die die Wildcards
expandiert.
Auflisten der Dateinamen, die einem Muster entsprechen
Welche(r) ls-Befehl(e) erzeugt/erzeugen diese Ausgabe,
wenn er/sie im Verzeichnis alkanes ausgeführt
wird/werden?
ethane.pdb methane.pdb
ls *t*ane.pdbls *t?ne.*ls *t??ne.pdbls ethane.*
Die Lösung lautet 3.
1. zeigt alle Dateien an, deren Namen null oder mehr
Zeichen (*) gefolgt von dem Buchstaben t, dann
null oder mehr Zeichen (*) gefolgt von ane.pdb
enthalten. Dies ergibt
ethane.pdb methane.pdb octane.pdb pentane.pdb.
2. zeigt alle Dateien, deren Namen mit null oder mehr
Zeichen beginnen (*), gefolgt von dem Buchstaben
t, dann ein einzelnes Zeichen (?), dann
ne. gefolgt von null oder mehr Zeichen (*).
Dies ergibt octane.pdb und pentane.pdb, aber
keine Übereinstimmung mit etwas, das auf thane.pdb
endet.
3. behebt die Probleme von Option 2, indem zwei Zeichen
(??) zwischen t und ne gefunden
werden. Dies ist die Lösung.
4. zeigt nur Dateien, die mit ethane.
beginnen.
Mehr über Wildcards
Sam hat ein Verzeichnis mit Kalibrierungsdaten, Datensätzen und Beschreibungen der Datensätze:
BASH
.
├── 2015-10-23-calibration.txt
├── 2015-10-23-dataset1.txt
├── 2015-10-23-dataset2.txt
├── 2015-10-23-dataset_overview.txt
├── 2015-10-26-calibration.txt
├── 2015-10-26-dataset1.txt
├── 2015-10-26-dataset2.txt
├── 2015-10-26-dataset_overview.txt
├── 2015-11-23-calibration.txt
├── 2015-11-23-dataset1.txt
├── 2015-11-23-dataset2.txt
├── 2015-11-23-dataset_overview.txt
├── backup
│ ├── calibration
│ └── datasets
└── send_to_bob
├── all_datasets_created_on_a_23rd
└── all_november_files
Bevor sie zu einer weiteren Exkursion aufbricht, möchte sie ihre Daten sichern und einige Datensätze an ihren Kollegen Bob schicken. Sam verwendet die folgenden Befehle, um diese Aufgabe zu erledigen:
BASH
$ cp *dataset* backup/datasets
$ cp ____calibration____ backup/calibration
$ cp 2015-____-____ send_to_bob/all_november_files/
$ cp ____ send_to_bob/all_datasets_created_on_a_23rd/
Hilf Sam, indem du die Lücken ausfüllst.
Die resultierende Verzeichnisstruktur sollte wie folgt aussehen
BASH
.
├── 2015-10-23-calibration.txt
├── 2015-10-23-dataset1.txt
├── 2015-10-23-dataset2.txt
├── 2015-10-23-dataset_overview.txt
├── 2015-10-26-calibration.txt
├── 2015-10-26-dataset1.txt
├── 2015-10-26-dataset2.txt
├── 2015-10-26-dataset_overview.txt
├── 2015-11-23-calibration.txt
├── 2015-11-23-dataset1.txt
├── 2015-11-23-dataset2.txt
├── 2015-11-23-dataset_overview.txt
├── backup
│ ├── calibration
│ │ ├── 2015-10-23-calibration.txt
│ │ ├── 2015-10-26-calibration.txt
│ │ └── 2015-11-23-calibration.txt
│ └── datasets
│ ├── 2015-10-23-dataset1.txt
│ ├── 2015-10-23-dataset2.txt
│ ├── 2015-10-23-dataset_overview.txt
│ ├── 2015-10-26-dataset1.txt
│ ├── 2015-10-26-dataset2.txt
│ ├── 2015-10-26-dataset_overview.txt
│ ├── 2015-11-23-dataset1.txt
│ ├── 2015-11-23-dataset2.txt
│ └── 2015-11-23-dataset_overview.txt
└── send_to_bob
├── all_datasets_created_on_a_23rd
│ ├── 2015-10-23-dataset1.txt
│ ├── 2015-10-23-dataset2.txt
│ ├── 2015-10-23-dataset_overview.txt
│ ├── 2015-11-23-dataset1.txt
│ ├── 2015-11-23-dataset2.txt
│ └── 2015-11-23-dataset_overview.txt
└── all_november_files
├── 2015-11-23-calibration.txt
├── 2015-11-23-dataset1.txt
├── 2015-11-23-dataset2.txt
└── 2015-11-23-dataset_overview.txt
Organisieren von Verzeichnissen und Dateien
Jamie arbeitet an einem Projekt und stellt fest, dass ihre Dateien nicht sehr gut organisiert sind:
AUSGABE
analyzed/ fructose.dat raw/ sucrose.dat
Die Dateien fructose.dat und sucrose.dat
enthalten die Ausgabe ihrer Datenanalyse. Welche(n) Befehl(e), der/die
in dieser Lektion behandelt wurde(n), muss sie ausführen, damit die
folgenden Befehle die gezeigte Ausgabe erzeugen?
AUSGABE
analyzed/ raw/
AUSGABE
fructose.dat sucrose.dat
Reproduzieren einer Ordnerstruktur
Sie beginnen ein neues Experiment und möchten die Verzeichnisstruktur Ihres vorherigen Experiments duplizieren, damit Sie neue Daten hinzufügen können.
Angenommen, das vorherige Experiment befindet sich in einem Ordner
namens 2016-05-18, der einen Ordner data
enthält, der wiederum Ordner namens raw und
processed enthält, die Datendateien enthalten. Das Ziel ist
es, die Ordnerstruktur des Ordners 2016-05-18 in einen
Ordner namens 2016-05-20 zu kopieren, so dass die
endgültige Verzeichnisstruktur wie folgt aussieht:
AUSGABE
2016-05-20/
└── data
├── processed
└── raw
Welcher der folgenden Befehle würde dieses Ziel erreichen? Was würden die anderen Befehle bewirken?
Die ersten beiden Befehlssätze erreichen dieses Ziel. Der erste Satz verwendet relative Pfade, um das oberste Verzeichnis vor den Unterverzeichnissen zu erstellen.
Der dritte Satz von Befehlen gibt einen Fehler, weil das
Standardverhalten von mkdir kein Unterverzeichnis eines
nicht existierenden Verzeichnisses erstellt: die Ordner der
Zwischenebene müssen zuerst erstellt werden.
Der vierte Satz von Befehlen erreicht dieses Ziel. Denken Sie daran,
dass die Option -p, gefolgt von einem Pfad zu einem oder
mehreren Verzeichnissen, mkdir veranlasst, alle dazwischen
liegenden Unterverzeichnisse zu erstellen, wie es erforderlich ist.
Der letzte Satz von Befehlen erzeugt die Verzeichnisse “raw” und “processed” auf derselben Ebene wie das Verzeichnis “data”.
-
cp [old] [new]kopiert eine Datei. -
mkdir [path]ein neues Verzeichnis erstellt. -
mv [old] [new]verschiebt (benennt) eine Datei oder ein Verzeichnis um. -
rm [path]entfernt (löscht) eine Datei. -
*passt auf null oder mehr Zeichen in einem Dateinamen, also passt*.txtauf alle Dateien, die auf.txtenden. -
?passt auf jedes einzelne Zeichen in einem Dateinamen, also passt?.txtaufa.txt, aber nicht aufany.txt. - Die Verwendung des Steuerschlüssels kann auf viele Arten beschrieben
werden, einschließlich
Ctrl-X,Control-Xund^X. - Die Shell hat keinen Mülleimer: Wenn etwas gelöscht ist, ist es wirklich weg.
- Die meisten Dateinamen sind
something.extension. Die Erweiterung ist nicht erforderlich und garantiert nichts, wird aber normalerweise verwendet, um die Art der Daten in der Datei anzugeben. - Abhängig von der Art Ihrer Arbeit benötigen Sie möglicherweise einen leistungsfähigeren Texteditor als Nano.
Content from Pipes und Filter
Zuletzt aktualisiert am 2025-10-23 | Diese Seite bearbeiten
Übersicht
Fragen
- Wie kann ich vorhandene Befehle kombinieren, um eine gewünschte Ausgabe zu erzeugen?
- Wie kann ich nur einen Teil der Ausgabe anzeigen?
Ziele
- Erklären Sie den Vorteil der Verknüpfung von Befehlen mit Pipes und Filtern.
- Kombiniere Sequenzen von Befehlen, um eine neue Ausgabe zu erhalten
- Leite die Ausgabe eines Befehls in eine Datei um.
- Erkläre, was normalerweise passiert, wenn ein Programm oder eine Pipeline keine Eingaben zu verarbeiten hat.
Nachdem wir nun ein paar grundlegende Befehle kennen, können wir uns
endlich der mächtigsten Eigenschaft der Shell zuwenden: der
Leichtigkeit, mit der sie uns erlaubt, bestehende Programme auf neue
Weise zu kombinieren. Wir beginnen mit dem Verzeichnis
shell-lesson-data/exercise-data/alkanes, das sechs Dateien
enthält, die einige einfache organische Moleküle beschreiben. Die
Erweiterung .pdb zeigt an, dass diese Dateien im Protein
Data Bank Format sind, einem einfachen Textformat, das den Typ und die
Position jedes Atoms im Molekül angibt.
AUSGABE
cubane.pdb methane.pdb pentane.pdb
ethane.pdb octane.pdb propane.pdb
Lassen Sie uns einen Beispielbefehl ausführen:
AUSGABE
20 156 1158 cubane.pdb
wc ist der ‘word count’ Befehl: er zählt die Anzahl der
Zeilen, Wörter und Zeichen in Dateien (und gibt die Werte in dieser
Reihenfolge von links nach rechts zurück).
Wenn wir den Befehl wc *.pdb ausführen, passt das
* in *.pdb auf null oder mehr Zeichen, so dass
die Shell *.pdb in eine Liste aller .pdb
Dateien im aktuellen Verzeichnis verwandelt:
AUSGABE
20 156 1158 cubane.pdb
12 84 622 ethane.pdb
9 57 422 methane.pdb
30 246 1828 octane.pdb
21 165 1226 pentane.pdb
15 111 825 propane.pdb
107 819 6081 total
Beachten Sie, dass wc *.pdb auch die Gesamtzahl aller
Zeilen in der letzten Zeile der Ausgabe anzeigt.
Wenn wir wc -l statt nur wc ausführen,
zeigt die Ausgabe nur die Anzahl der Zeilen pro Datei:
AUSGABE
20 cubane.pdb
12 ethane.pdb
9 methane.pdb
30 octane.pdb
21 pentane.pdb
15 propane.pdb
107 total
Die Optionen -m und -w können auch mit dem
Befehl wc verwendet werden, um nur die Anzahl der Zeichen
bzw. die Anzahl der Wörter anzuzeigen.
Warum passiert nichts?
Was passiert, wenn ein Befehl eine Datei verarbeiten soll, wir ihm aber keinen Dateinamen geben? Zum Beispiel, was passiert, wenn wir eingeben:
schreibt, aber nach dem Befehl nicht *.pdb (oder
irgendetwas anderes) einträgt? Da es keine Dateinamen hat, geht
wc davon aus, dass es Eingaben an der Eingabeaufforderung
verarbeiten soll, also sitzt es einfach da und wartet darauf, dass wir
ihm interaktiv Daten geben. Von außen sehen wir jedoch nur, wie es
dasitzt, und der Befehl scheint nichts zu tun.
Wenn Sie einen solchen Fehler machen, können Sie aus diesem Zustand herauskommen, indem Sie die Steuerungstaste (Strg) gedrückt halten und einmal den Buchstaben C drücken: Strg+C. Lassen Sie dann beide Tasten los.
Erfassen der Ausgabe von Befehlen
Welche dieser Dateien enthält die wenigsten Zeilen? Diese Frage ist leicht zu beantworten, wenn es nur sechs Dateien gibt, aber was wäre, wenn es 6000 wären? Unser erster Schritt zur Lösung besteht darin, den Befehl auszuführen:
Das Größer-als-Symbol, >, weist die Shell an, die
Ausgabe des Befehls in eine Datei umzuleiten, anstatt
sie auf dem Bildschirm auszugeben. Dieser Befehl gibt keine
Bildschirmausgabe aus, da alles, was wc gedruckt hätte,
stattdessen in die Datei lengths.txt gelangt ist. Wenn die
Datei vor der Ausgabe des Befehls nicht existiert, wird die Shell die
Datei erstellen. Wenn die Datei bereits existiert, wird sie
stillschweigend überschrieben, was zu Datenverlusten führen kann. Daher
ist bei redirect-Befehlen Vorsicht geboten.
ls lengths.txt bestätigt, dass die Datei existiert:
AUSGABE
lengths.txt
Wir können nun den Inhalt von lengths.txt mit
cat lengths.txt auf den Bildschirm schicken. Der Befehl
cat hat seinen Namen von ‘concatenate’, d.h. zusammenfügen,
und er gibt den Inhalt von Dateien nacheinander aus. In diesem Fall gibt
es nur eine Datei, also zeigt uns cat nur, was sie
enthält:
AUSGABE
20 cubane.pdb
12 ethane.pdb
9 methane.pdb
30 octane.pdb
21 pentane.pdb
15 propane.pdb
107 total
Seitenweise Ausgabe
Aus Gründen der Bequemlichkeit und Konsistenz werden wir in dieser
Lektion weiterhin den Befehl cat verwenden, der jedoch den
Nachteil hat, dass er immer die gesamte Datei auf den Bildschirm
ausgibt. In der Praxis ist der Befehl less (z.B.
less lengths.txt) nützlicher. Dieser Befehl zeigt einen
Bildschirminhalt der Datei an und hält dann an. Sie können mit der
Leertaste einen Bildschirm vorwärts oder mit b einen
Bildschirm zurück gehen. Drücken Sie q zum Beenden.
Filtern der Ausgabe
Als nächstes werden wir den Befehl sort benutzen, um den
Inhalt der Datei lengths.txt zu sortieren. Aber zuerst
werden wir eine Übung machen, um ein wenig über den Sortierbefehl zu
lernen:
Was macht sort -n?
Die Datei shell-lesson-data/exercise-data/numbers.txt
enthält die folgenden Zeilen:
10
2
19
22
6
Wenn wir sort auf dieser Datei ausführen, ist die
Ausgabe:
AUSGABE
10
19
2
22
6
Wenn wir sort -n auf dieselbe Datei anwenden, erhalten
wir stattdessen Folgendes:
AUSGABE
2
6
10
19
22
Erkläre, warum -n diesen Effekt hat.
Die Option -n legt eine numerische statt einer
alphanumerischen Sortierung fest.
Wir werden auch die Option -n verwenden, um anzugeben,
dass die Sortierung numerisch statt alphanumerisch ist. Dadurch wird die
Datei nicht verändert, sondern das sortierte Ergebnis auf den
Bildschirm übertragen:
AUSGABE
9 methane.pdb
12 ethane.pdb
15 propane.pdb
20 cubane.pdb
21 pentane.pdb
30 octane.pdb
107 total
Wir können die sortierte Liste von Zeilen in eine andere temporäre
Datei namens sorted-lengths.txt stellen, indem wir
> sorted-lengths.txt nach dem Befehl einfügen, genauso
wie wir > lengths.txt benutzt haben, um die Ausgabe von
wc in lengths.txt zu stellen. Wenn wir das
getan haben, können wir einen weiteren Befehl namens head
ausführen, um die ersten Zeilen in sorted-lengths.txt zu
erhalten:
AUSGABE
9 methane.pdb
Die Verwendung von -n 1 mit head sagt ihm,
dass wir nur die erste Zeile der Datei wollen; -n 20 würde
die ersten 20 bekommen, und so weiter. Da
sorted-lengths.txt die Längen unserer Dateien in der
Reihenfolge vom kleinsten zum größten Wert enthält, muss die Ausgabe von
head die Datei mit den wenigsten Zeilen sein.
Umleitung auf dieselbe Datei
Was bedeutet >>?
Wir haben die Verwendung von > gesehen, aber es gibt
einen ähnlichen Operator >>, der etwas anders
funktioniert. Wir werden die Unterschiede zwischen diesen beiden
Operatoren kennenlernen, indem wir einige Zeichenketten ausgeben. Mit
dem Befehl echo können wir Zeichenketten ausgeben, z.B.
AUSGABE
The echo command prints text
Testen Sie nun die folgenden Befehle, um den Unterschied zwischen den beiden Operatoren herauszufinden:
und:
Tipp: Versuchen Sie, jeden Befehl zweimal hintereinander auszuführen und dann die Ausgabedateien zu untersuchen.
Im ersten Beispiel mit > wird die Zeichenkette
‘hello’ nach testfile01.txt geschrieben, aber die Datei
wird jedes Mal überschrieben, wenn wir den Befehl ausführen.
Im zweiten Beispiel sehen wir, dass der
>>-Operator auch ‘hallo’ in eine Datei schreibt (in
diesem Fall testfile02.txt), aber die Zeichenkette an die
Datei anhängt, wenn sie bereits existiert (d.h. wenn wir es zum zweiten
Mal ausführen).
Daten anhängen
Wir haben bereits den Befehl head kennengelernt, der
Zeilen vom Anfang einer Datei ausgibt. der Befehl tail ist
ähnlich, druckt aber stattdessen Zeilen vom Ende einer Datei aus.
Betrachten Sie die Datei
shell-lesson-data/exercise-data/animal-counts/animals.csv.
Wählen Sie nach diesen Befehlen die Antwort aus, die der Datei
animals-subset.csv entspricht:
- Die ersten drei Zeilen von
animals.csv - Die letzten beiden Zeilen von
animals.csv - Die ersten drei Zeilen und die letzten zwei Zeilen von
animals.csv - Die zweite und dritte Zeile von
animals.csv
Option 3 ist richtig. Damit Option 1 richtig ist, würden wir nur den
Befehl head ausführen. Damit Option 2 richtig ist, würden
wir nur den Befehl tail ausführen. Damit Option 4 richtig
ist, müssen wir die Ausgabe von head in
tail -n 2 leiten, indem wir
head -n 3 animals.csv | tail -n 2 > animals-subset.csv
ausführen
Übergabe der Ausgabe an einen anderen Befehl
In unserem Beispiel, in dem es darum geht, die Datei mit den
wenigsten Zeilen zu finden, verwenden wir zwei Zwischendateien
lengths.txt und sorted-lengths.txt, um die
Ausgabe zu speichern. Das ist eine verwirrende Arbeitsweise, denn selbst
wenn man einmal verstanden hat, was wc, sort
und head tun, machen es diese Zwischendateien schwer zu
verstehen, was vor sich geht. Wir können es einfacher machen, indem wir
sort und head zusammen ausführen:
AUSGABE
9 methane.pdb
Der vertikale Balken, |, zwischen den beiden Befehlen
wird pipe genannt. Er sagt der Shell, dass wir die
Ausgabe des Befehls auf der linken Seite als Eingabe für den Befehl auf
der rechten Seite verwenden wollen.
Dadurch ist die Datei sorted-lengths.txt überflüssig
geworden.
Kombinieren mehrerer Befehle
Nichts hindert uns daran, Pipes hintereinander zu schalten. Wir
können zum Beispiel die Ausgabe von wc direkt an
sort schicken, und dann die resultierende Ausgabe an
head. Dies macht Zwischendateien überflüssig.
Wir beginnen damit, eine Pipe zu benutzen, um die Ausgabe von
wc nach sort zu schicken:
AUSGABE
9 methane.pdb
12 ethane.pdb
15 propane.pdb
20 cubane.pdb
21 pentane.pdb
30 octane.pdb
107 total
Wir können diese Ausgabe dann durch eine weitere Pipe an
head schicken, so dass die gesamte Pipeline so
aussieht:
AUSGABE
9 methane.pdb
Das ist genau so, als würde ein Mathematiker Funktionen wie
log(3x) verschachteln und sagen ‘der Logarithmus von dreimal
x’. In unserem Fall lautet der Algorithmus ‘Kopf der Sortierung
der Zeilenzahl von *.pdb’.
Die Umleitung und die Pipes, die in den letzten Befehlen verwendet wurden, sind unten dargestellt:
{alt=“Redirects und Pipes
von verschiedenen Befehlen:”wc -l *.pdb” leitet die Ausgabe an die Shell
weiter. “wc -l *.pdb > lengths” leitet die Ausgabe in die Datei
“lengths”. “wc -l *.pdb | sort -n | head -n 1” erstellt eine Pipeline,
bei der die Ausgabe des “wc”-Befehls die Eingabe für den “sort”-Befehl
ist, die Ausgabe des “sort”-Befehls die Eingabe für den “head”-Befehl
ist und die Ausgabe des “head”-Befehls an die Shell geleitet wird”}
Piping-Befehle zusammen
In unserem aktuellen Verzeichnis wollen wir die 3 Dateien mit der geringsten Anzahl von Zeilen finden. Welcher der unten aufgeführten Befehle würde funktionieren?
wc -l * > sort -n > head -n 3wc -l * | sort -n | head -n 1-3wc -l * | head -n 3 | sort -nwc -l * | sort -n | head -n 3
Option 4 ist die Lösung. Das Pipe-Zeichen | wird
verwendet, um die Ausgabe eines Befehls mit der Eingabe eines anderen zu
verbinden.> wird verwendet, um die Standardausgabe in
eine Datei umzuleiten. Probieren Sie es im Verzeichnis
shell-lesson-data/exercise-data/alkanes aus!
Werkzeuge, die zusammenarbeiten sollen
Diese Idee der Verknüpfung von Programmen ist der Grund, warum Unix
so erfolgreich ist. Anstatt riesige Programme zu erstellen, die
versuchen, viele verschiedene Dinge zu tun, konzentrieren sich die
Unix-Programmierer darauf, viele einfache Werkzeuge zu entwickeln, die
jeweils eine Aufgabe gut erledigen und gut miteinander arbeiten. Dieses
Programmiermodell wird “Pipes und Filter” genannt. Wir haben bereits
Pipes gesehen; ein Filter ist ein Programm wie
wc oder sort, das einen Eingabestrom in einen
Ausgabestrom umwandelt. Fast alle Unix-Standardwerkzeuge können auf
diese Weise arbeiten. Wenn sie nicht anders angewiesen werden, lesen sie
von der Standardeingabe, machen etwas mit dem, was sie gelesen haben,
und schreiben auf die Standardausgabe.
Der Schlüssel ist, dass jedes Programm, das Textzeilen von der Standardeingabe liest und Textzeilen in die Standardausgabe schreibt, mit jedem anderen Programm kombiniert werden kann, das sich ebenfalls so verhält. Sie können und sollten Ihre Programme auf diese Weise schreiben, damit Sie und andere Leute diese Programme in Pipes einbinden können, um ihre Leistung zu vervielfachen.
Pipe Verständnisabfrage
Eine Datei namens animals.csv (im Ordner
shell-lesson-data/exercise-data/animal-counts) enthält die
folgenden Daten:
2012-11-05,deer,5
2012-11-05,rabbit,22
2012-11-05,raccoon,7
2012-11-06,rabbit,19
2012-11-06,deer,2
2012-11-06,fox,4
2012-11-07,rabbit,16
2012-11-07,bear,1
Welcher Text durchläuft jede der Pipes und die endgültige Umleitung
in der folgenden Pipeline? Beachten Sie, dass der Befehl
sort -r in umgekehrter Reihenfolge sortiert.
Tipp: Bauen Sie die Pipeline nach und nach auf, um Ihr Verständnis zu testen
Der Befehl head extrahiert die ersten 5 Zeilen aus
animals.csv. Dann werden die letzten 3 Zeilen mit dem
Befehl tail aus den vorherigen 5 Zeilen extrahiert. Mit dem
Befehl sort -r werden diese 3 Zeilen in umgekehrter
Reihenfolge sortiert. Schließlich wird die Ausgabe in eine Datei
umgeleitet: ,final.txt. Der Inhalt dieser Datei kann durch
Ausführen von cat final.txt überprüft werden. Die Datei
sollte die folgenden Zeilen enthalten:
2012-11-06,rabbit,19
2012-11-06,deer,2
2012-11-05,raccoon,7
Pipe-Konstruktion
Betrachten Sie für die Datei animals.csv aus der
vorherigen Übung den folgenden Befehl:
Der Befehl cut wird verwendet, um bestimmte Abschnitte
jeder Zeile in der Datei zu entfernen oder “auszuschneiden”, und
cut erwartet, dass die Zeilen durch ein
Tab-Zeichen in Spalten getrennt sind. Ein Zeichen, das auf
diese Weise verwendet wird, nennt man ein
Begrenzungszeichen. Im obigen Beispiel verwenden wir
die Option -d, um das Komma als Begrenzungszeichen
anzugeben. Wir haben auch die Option -f verwendet, um
anzugeben, dass wir das zweite Feld (Spalte) extrahieren wollen. Dies
ergibt die folgende Ausgabe:
AUSGABE
deer
rabbit
raccoon
rabbit
deer
fox
rabbit
bear
Der Befehl uniq filtert benachbarte übereinstimmende
Zeilen in einer Datei heraus. Wie könnten Sie diese Pipeline (mit
uniq und einem anderen Befehl) erweitern, um
herauszufinden, welche Tiere die Datei enthält (ohne Duplikate in ihren
Namen)?
Welche Pipe?
Die Datei animals.csv enthält 8 Zeilen mit Daten, die
wie folgt formatiert sind:
AUSGABE
2012-11-05,deer,5
2012-11-05,rabbit,22
2012-11-05,raccoon,7
2012-11-06,rabbit,19
...
Der uniq-Befehl hat eine -c-Option, die die
Anzahl der Vorkommen einer Zeile in der Eingabe angibt. Angenommen, Ihr
aktuelles Verzeichnis ist
shell-lesson-data/exercise-data/animal-counts. Welchen
Befehl würden Sie verwenden, um eine Tabelle zu erstellen, die die
Gesamtzahl der einzelnen Tierarten in der Datei anzeigt?
sort animals.csv | uniq -csort -t, -k2,2 animals.csv | uniq -ccut -d, -f 2 animals.csv | uniq -ccut -d, -f 2 animals.csv | sort | uniq -ccut -d, -f 2 animals.csv | sort | uniq -c | wc -l
Option 4. ist die richtige Antwort. Wenn Sie Schwierigkeiten haben zu
verstehen, warum, versuchen Sie die Befehle oder Unterabschnitte der
Pipelines auszuführen (stellen Sie sicher, dass Sie sich im Verzeichnis
shell-lesson-data/exercise-data/animal-counts
befinden).
Nelle’s Pipeline: Prüfen von Dateien
Nelle hat ihre Proben durch die Testmaschinen laufen lassen und 17
Dateien in dem zuvor beschriebenen Verzeichnis
north-pacific-gyre erstellt. Zur schnellen Überprüfung
tippt Nelle, ausgehend vom Verzeichnis shell-lesson-data,
ein:
Die Ausgabe besteht aus 18 Zeilen, die wie folgt aussehen:
AUSGABE
300 NENE01729A.txt
300 NENE01729B.txt
300 NENE01736A.txt
300 NENE01751A.txt
300 NENE01751B.txt
300 NENE01812A.txt
... ...
Jetzt tippt sie dies:
AUSGABE
240 NENE02018B.txt
300 NENE01729A.txt
300 NENE01729B.txt
300 NENE01736A.txt
300 NENE01751A.txt
Hoppla: eine der Dateien ist 60 Zeilen kürzer als die anderen. Als sie zurückgeht und nachsieht, stellt sie fest, dass sie den Test um 8 Uhr an einem Montagmorgen durchgeführt hat - wahrscheinlich hat jemand den Rechner am Wochenende benutzt und sie hat vergessen, ihn zurückzusetzen. Bevor sie die Probe erneut durchführt, prüft sie, ob irgendwelche Dateien zu viele Daten haben:
AUSGABE
300 NENE02040B.txt
300 NENE02040Z.txt
300 NENE02043A.txt
300 NENE02043B.txt
5040 total
Diese Zahlen sehen gut aus — aber was macht das ‘Z’ dort in der drittletzten Zeile? Alle ihre Proben sollten mit “A” oder “B” gekennzeichnet sein; ihr Labor verwendet vereinbarungsgemäß “Z”, um Proben mit fehlenden Informationen zu kennzeichnen. Um andere Proben dieser Art zu finden, geht sie folgendermaßen vor:
AUSGABE
NENE01971Z.txt NENE02040Z.txt
Als sie das Protokoll auf ihrem Laptop überprüft, ist für keine der
beiden Proben eine Tiefe aufgezeichnet. Da es zu spät ist, die
Informationen auf andere Weise zu erhalten, muss sie diese beiden
Dateien von ihrer Analyse ausschließen. Sie könnte sie mit
rm löschen, aber es gibt tatsächlich einige Analysen, die
sie später durchführen könnte, bei denen die Tiefe keine Rolle spielt.
Stattdessen muss sie später darauf achten, Dateien mit den
Platzhalterausdrücken NENE*A.txt NENE*B.txt
auszuwählen.
Unnötige Dateien entfernen
Angenommen, Sie möchten Ihre verarbeiteten Datendateien löschen und
nur Ihre Rohdateien und das Verarbeitungsskript behalten, um
Speicherplatz zu sparen. Die Rohdateien enden auf .dat und
die verarbeiteten Dateien auf .txt. Welche der folgenden
Möglichkeiten würde alle verarbeiteten Datendateien und nur die
verarbeiteten Datendateien löschen?
rm ?.txtrm *.txtrm * .txtrm *.*
- Dies würde
.txtDateien mit einstelligen Namen entfernen - Dies ist die richtige Antwort
- Die Shell würde
*so erweitern, dass es auf alles im aktuellen Verzeichnis passt, also würde der Befehl versuchen, alle passenden Dateien und eine zusätzliche Datei namens.txtzu entfernen - Die Shell expandiert
*.*, um alle Dateinamen zu finden, die mindestens ein.enthalten, einschließlich der verarbeiteten Dateien (.txt) und der Rohdateien (.dat)
-
wczählt Zeilen, Wörter und Zeichen in ihren Eingaben. -
catzeigt den Inhalt ihrer Eingänge an. -
sortsortiert ihre Eingaben. -
headzeigt die ersten 10 Zeilen seiner Eingabe standardmäßig ohne zusätzliche Argumente an. -
tailzeigt die letzten 10 Zeilen seiner Eingabe standardmäßig ohne zusätzliche Argumente an. -
command > [file]leitet die Ausgabe eines Befehls in eine Datei um (und überschreibt dabei den vorhandenen Inhalt). -
command >> [file]hängt die Ausgabe eines Befehls an eine Datei an. -
[first] | [second]ist eine Pipeline: die Ausgabe des ersten Befehls wird als Eingabe für den zweiten verwendet. - Die beste Art, die Shell zu benutzen, ist, Pipes zu benutzen, um einfache Einzweckprogramme (Filter) zu kombinieren.
Content from Schleifen
Zuletzt aktualisiert am 2025-10-23 | Diese Seite bearbeiten
Übersicht
Fragen
- Wie kann ich die gleichen Aktionen für viele verschiedene Dateien durchführen?
Ziele
- Schreiben Sie eine Schleife, die einen oder mehrere Befehle separat auf jede Datei in einer Gruppe von Dateien anwendet.
- Verfolgen Sie die Werte, die eine Schleifenvariable während der Ausführung der Schleife annimmt.
- Erkläre den Unterschied zwischen dem Namen einer Variablen und ihrem Wert.
- Erkläre, warum Leerzeichen und einige Satzzeichen nicht in Dateinamen verwendet werden sollten.
- Demonstrieren Sie, wie Sie sehen können, welche Befehle kürzlich ausgeführt worden sind.
- Wiederholung kürzlich ausgeführter Befehle, ohne sie neu zu tippen.
Schleifen sind ein Programmierkonstrukt, das es uns ermöglicht, einen Befehl oder eine Reihe von Befehlen für jedes Element in einer Liste zu wiederholen. Als solche sind sie der Schlüssel zur Produktivitätssteigerung durch Automatisierung. Ähnlich wie bei Platzhaltern und der Tabulatorvervollständigung reduziert die Verwendung von Schleifen auch die Anzahl der erforderlichen Eingaben (und damit die Anzahl der Tippfehler).
Angenommen, wir haben mehrere hundert Genomdateien mit den Namen
basilisk.dat, minotaur.dat und
unicorn.dat. Für dieses Beispiel verwenden wir das
Verzeichnis exercise-data/creatures, das nur drei
Beispieldateien enthält, aber die Prinzipien können auf viele weitere
Dateien gleichzeitig angewendet werden.
Die Struktur dieser Dateien ist die gleiche: der gemeinsame Name, die Klassifizierung und das Aktualisierungsdatum werden in den ersten drei Zeilen angegeben, die DNA-Sequenzen in den folgenden Zeilen. Schauen wir uns die Dateien an:
Wir möchten die Klassifizierung für jede Art ausgeben, die in der
zweiten Zeile jeder Datei angegeben ist. Für jede Datei müssten wir den
Befehl head -n 2 ausführen und diesen an
tail -n 1 weiterleiten. Wir werden eine Schleife verwenden,
um dieses Problem zu lösen, aber sehen wir uns zunächst die allgemeine
Form einer Schleife an, indem wir den folgenden Pseudocode
verwenden:
BASH
# Das Wort „for“ kennzeichnet den Beginn eines „For-Schleifen“-Befehls.
for thing in list_of_things
# Das Wort „do“ kennzeichnet den Beginn der Jobausführungsliste.
do
# Einrückungen innerhalb der Schleife sind nicht erforderlich, verbessern jedoch die Lesbarkeit.
operation oder command welches $thing verwendet
# Das Wort „done“ kennzeichnet das Ende einer Schleife.
done
und wir können dies auf unser Beispiel wie folgt anwenden:
BASH
$ for filename in basilisk.dat minotaur.dat unicorn.dat
> do
> echo $filename
> head -n 2 $filename | tail -n 1
> done
AUSGABE
basilisk.dat
CLASSIFICATION: basiliscus vulgaris
minotaur.dat
CLASSIFICATION: bos hominus
unicorn.dat
CLASSIFICATION: equus monoceros
Folgen Sie der Eingabeaufforderung
Der Shell-Prompt wechselt von $ zu > und
wieder zurück, während wir in unserer Schleife tippen. Der zweite
Prompt, >, ist anders, um uns daran zu erinnern, dass
wir noch nicht mit der Eingabe eines kompletten Befehls fertig sind. Ein
Semikolon, ;, kann verwendet werden, um zwei Befehle zu
trennen, die in einer einzigen Zeile stehen.
Wenn die Shell das Schlüsselwort for sieht, weiß sie,
dass sie einen Befehl (oder eine Gruppe von Befehlen) für jedes Element
in einer Liste einmal wiederholen muss. Jedes Mal, wenn die Schleife
läuft (Iteration genannt), wird ein Eintrag in der Liste der Reihe nach
der Variablen zugewiesen, und die Befehle innerhalb der
Schleife werden ausgeführt, bevor zum nächsten Eintrag in der Liste
übergegangen wird. Innerhalb der Schleife fragen wir den Wert der
Variable ab, indem wir ihr $ voranstellen. Das
$ weist den Shell-Interpreter an, die Variable als
Variablennamen zu behandeln und ihren Wert an ihrer Stelle zu ersetzen,
anstatt sie als Text oder externen Befehl zu behandeln.
In diesem Beispiel besteht die Liste aus drei Dateinamen:
basilisk.dat, minotaur.dat, und
unicorn.dat. Jedes Mal, wenn die Schleife durchläuft,
verwenden wir zunächst echo, um den Wert auszugeben, den
die Variable $filename gerade hat. Dies ist für das
Ergebnis nicht notwendig, aber für uns hier von Vorteil, um leichter
folgen zu können. Als Nächstes führen wir den Befehl head
in der Datei aus, auf die $filename gerade verweist. Beim
ersten Durchlauf der Schleife ist $filename
basilisk.dat. Der Interpreter führt den Befehl
head auf basilisk.dat aus und leitet die
ersten beiden Zeilen an den Befehl tail weiter, der dann
die zweite Zeile von basilisk.dat ausgibt. Bei der zweiten
Iteration wird $filename zu minotaur.dat.
Dieses Mal lässt die Shell head auf
minotaur.dat laufen und leitet die ersten beiden Zeilen an
den Befehl tail weiter, der dann die zweite Zeile von
minotaur.dat ausgibt. Bei der dritten Iteration wird
$filename zu unicorn.dat, also führt die Shell
den Befehl head auf dieser Datei aus, und tail
auf der Ausgabe davon. Da die Liste nur drei Einträge enthielt, verlässt
die Shell die for-Schleife.
Gleiche Symbole, unterschiedliche Bedeutungen
Hier sehen wir, dass > als Shell-Prompt verwendet
wird, während > auch zur Umleitung der Ausgabe verwendet
wird. In ähnlicher Weise wird $ als Shell-Prompt benutzt,
aber, wie wir zuvor gesehen haben, wird es auch benutzt, um die Shell zu
bitten, den Wert einer Variablen zu erhalten.
Wenn die Shell > oder $
ausgibt, erwartet sie, dass Sie etwas eingeben, und das Symbol ist ein
Prompt.
Wenn Sie selbst > oder $
eintippen, ist das eine Anweisung von Ihnen, dass die Shell die Ausgabe
umleiten oder den Wert einer Variablen holen soll.
Bei der Verwendung von Variablen ist es auch möglich, die Namen in
geschweifte Klammern zu setzen, um den Variablennamen klar abzugrenzen:
$filename entspricht ${filename}, ist aber
anders als ${file}name. Diese Schreibweise finden Sie
vielleicht auch in anderen Programmen.
Wir haben die Variable in dieser Schleife filename
genannt, um ihren Zweck für den menschlichen Leser zu verdeutlichen. Der
Shell selbst ist es egal, wie die Variable genannt wird; wenn wir diese
Schleife so schreiben würden:
oder:
BASH
$ for temperature in basilisk.dat minotaur.dat unicorn.dat
> do
> head -n 2 $temperature | tail -n 1
> done
Es würde genau so funktionieren. Tun Sie das nicht.
Programme sind nur dann nützlich, wenn die Leute sie verstehen können,
daher erhöhen bedeutungslose Namen (wie x) oder
irreführende Namen (wie temperature) die
Wahrscheinlichkeit, dass das Programm nicht das tut, was seine Leser
denken, dass es tut.
In den obigen Beispielen hätte man den Variablen (thing,
filename, x und temperature)
jeden anderen Namen geben können, solange er sowohl für die Person, die
den Code schreibt, als auch für die Person, die ihn liest, sinnvoll
ist.
Beachten Sie auch, dass Schleifen für andere Dinge als Dateinamen verwendet werden können, wie z.B. eine Liste von Zahlen oder eine Teilmenge von Daten.
Schreiben Sie Ihre eigene Schleife
Wie würden Sie eine Schleife schreiben, die alle 10 Zahlen von 0 bis 9 als Echo ausgibt?
Variablen in Schleifen
Diese Übung bezieht sich auf das Verzeichnis
shell-lesson-data/exercise-data/alkanes.
ls *.pdb gibt die folgende Ausgabe:
AUSGABE
cubane.pdb ethane.pdb methane.pdb octane.pdb pentane.pdb propane.pdb
Was ist die Ausgabe des folgenden Codes?
Wie lautet nun die Ausgabe des folgenden Codes?
Warum geben diese beiden Schleifen unterschiedliche Ergebnisse aus?
Der erste Codeblock gibt bei jeder Iteration der Schleife die gleiche
Ausgabe. Bash erweitert den Platzhalter *.pdb innerhalb des
Schleifenkörpers (sowie vor dem Start der Schleife), um alle Dateien zu
finden, die auf .pdb enden, und listet sie dann mit
ls auf. Die erweiterte Schleife würde wie folgt
aussehen:
BASH
$ for datafile in cubane.pdb ethane.pdb methane.pdb octane.pdb pentane.pdb propane.pdb
> do
> ls cubane.pdb ethane.pdb methane.pdb octane.pdb pentane.pdb propane.pdb
> done
AUSGABE
cubane.pdb ethane.pdb methane.pdb octane.pdb pentane.pdb propane.pdb
cubane.pdb ethane.pdb methane.pdb octane.pdb pentane.pdb propane.pdb
cubane.pdb ethane.pdb methane.pdb octane.pdb pentane.pdb propane.pdb
cubane.pdb ethane.pdb methane.pdb octane.pdb pentane.pdb propane.pdb
cubane.pdb ethane.pdb methane.pdb octane.pdb pentane.pdb propane.pdb
cubane.pdb ethane.pdb methane.pdb octane.pdb pentane.pdb propane.pdb
Der zweite Codeblock listet bei jeder Schleifeniteration eine andere
Datei auf. Der Wert der Variable datafile wird mit
$datafile ausgewertet und dann mit ls
aufgelistet.
AUSGABE
cubane.pdb
ethane.pdb
methane.pdb
octane.pdb
pentane.pdb
propane.pdb
Begrenzung von Dateimengen
Was wäre die Ausgabe, wenn die folgende Schleife im Verzeichnis
shell-lesson-data/exercise-data/alkanes ausgeführt
würde?
- Es sind keine Dateien aufgelistet.
- Alle Dateien sind aufgelistet.
- Nur
cubane.pdb,octane.pdbundpentane.pdbsind aufgeführt. - Nur
cubane.pdbist aufgeführt.
4 ist die richtige Antwort.* passt auf null oder mehr
Zeichen, so dass jeder Dateiname, der mit dem Buchstaben c beginnt,
gefolgt von null oder mehr anderen Zeichen, gefunden wird.
Begrenzung von Dateimengen (continued)
Wie würde sich die Ausgabe unterscheiden, wenn stattdessen dieser Befehl verwendet würde?
- Die gleichen Dateien würden aufgelistet werden.
- Diesmal werden alle Dateien aufgelistet.
- Diesmal werden keine Dateien aufgelistet.
- Die Dateien
cubane.pdbundoctane.pdbwerden aufgelistet. - Es wird nur die Datei
octane.pdbaufgelistet.
4 ist die richtige Antwort.* passt auf null oder mehr
Zeichen, also wird ein Dateiname mit null oder mehr Zeichen vor dem
Buchstaben c und null oder mehr Zeichen nach dem Buchstaben c
gefunden.
Speichern in einer Datei in einer Schleife - Teil eins
Was ist die Auswirkung dieser Schleife im Verzeichnis
shell-lesson-data/exercise-data/alkanes?
- Druckt
cubane.pdb,ethane.pdb,methane.pdb,octane.pdb,pentane.pdbundpropane.pdb, und der Text vonpropane.pdbwird in einer Datei namensalkanes.pdbgespeichert. - Druckt
cubane.pdb,ethane.pdbundmethane.pdb, und der Text aus allen drei Dateien wird zusammengefügt und in einer Datei namensalkanes.pdbgespeichert. - Druckt
cubane.pdb,ethane.pdb,methane.pdb,octane.pdb, undpentane.pdb, und der Text vonpropane.pdbwird in einer Datei namensalkanes.pdbgespeichert. - Keine der oben genannten.
- Der Text aus jeder Datei wird der Reihe nach in die Datei
alkanes.pdbgeschrieben. Allerdings wird die Datei bei jedem Schleifendurchlauf überschrieben, so dass der endgültige Inhalt vonalkanes.pdbder Text aus der Dateipropane.pdbist.
Speichern in einer Datei in einer Schleife - Teil Zwei
Was wäre die Ausgabe der folgenden Schleife, ebenfalls im Verzeichnis
shell-lesson-data/exercise-data/alkanes?
- Der gesamte Text von
cubane.pdb,ethane.pdb,methane.pdb,octane.pdbundpentane.pdbwürde verkettet und in einer Datei namensall.pdbgespeichert. - Der Text von
ethane.pdbwird in einer Datei namensall.pdbgespeichert. - Der gesamte Text von
cubane.pdb,ethane.pdb,methane.pdb,octane.pdb,pentane.pdbundpropane.pdbwürde konkateniert und in einer Datei namensall.pdbgespeichert. - Der gesamte Text von
cubane.pdb,ethane.pdb,methane.pdb,octane.pdb,pentane.pdbundpropane.pdbwürde auf dem Bildschirm ausgegeben und in einer Datei namensall.pdbgespeichert.
3 ist die richtige Antwort. >> hängt an eine Datei
an, anstatt sie mit der umgeleiteten Ausgabe eines Befehls zu
überschreiben. Da die Ausgabe des Befehls cat umgeleitet
wurde, wird nichts auf dem Bildschirm ausgegeben.
Lassen Sie uns mit unserem Beispiel im Verzeichnis
shell-lesson-data/exercise-data/creatures fortfahren. Hier
ist eine etwas kompliziertere Schleife:
Die Shell beginnt mit der Expansion von *.dat, um die
Liste der zu verarbeitenden Dateien zu erstellen. Der
Schleifenkörper führt dann zwei Befehle für jede dieser
Dateien aus. Der erste Befehl, echo, gibt seine
Befehlszeilenargumente auf der Standardausgabe aus. Zum Beispiel:
druckt:
AUSGABE
hello there
Da die Shell in diesem Fall $filename als Name einer
Datei expandiert, gibt echo $filename den Namen der Datei
aus. Beachten Sie, dass wir dies nicht so schreiben können:
weil dann beim ersten Durchlauf der Schleife, wenn
$filename zu basilisk.dat expandiert, die
Shell versuchen würde, basilisk.dat als Programm
auszuführen. Schließlich wählt die Kombination head und
tail die Zeilen 81-100 aus der zu verarbeitenden Datei aus
(vorausgesetzt, die Datei hat mindestens 100 Zeilen).
Leerzeichen in Namen
Leerzeichen werden verwendet, um die Elemente der Liste zu trennen, über die wir eine Schleife laufen lassen wollen. Wenn eines dieser Elemente ein Leerzeichen enthält, müssen wir es mit Anführungszeichen umgeben und dasselbe mit unserer Schleifenvariablen tun. Angenommen, unsere Datendateien sind benannt:
red dragon.dat
purple unicorn.dat
Um eine Schleife über diese Dateien zu ziehen, müssten wir doppelte Anführungszeichen wie folgt hinzufügen:
BASH
$ for filename in "red dragon.dat" "purple unicorn.dat"
> do
> head -n 100 "$filename" | tail -n 20
> done
Es ist einfacher, Leerzeichen (oder andere Sonderzeichen) in Dateinamen zu vermeiden.
Die obigen Dateien existieren nicht, wenn wir also den obigen Code
ausführen, kann der Befehl head sie nicht finden; die
zurückgegebene Fehlermeldung zeigt jedoch den Namen der erwarteten
Dateien an:
FEHLER
head: cannot open ‘red dragon.dat' for reading: No such file or directory
head: cannot open ‘purple unicorn.dat' for reading: No such file or directory
Versuchen Sie, die Anführungszeichen um $filename in der
obigen Schleife zu entfernen, um den Effekt der Anführungszeichen auf
Leerzeichen zu sehen. Beachten Sie, dass wir ein Ergebnis des
Schleifenbefehls für unicorn.dat erhalten, wenn wir diesen Code im
Verzeichnis creatures ausführen:
AUSGABE
head: cannot open ‘red' for reading: No such file or directory
head: cannot open ‘dragon.dat' for reading: No such file or directory
head: cannot open ‘purple' for reading: No such file or directory
CGGTACCGAA
AAGGGTCGCG
CAAGTGTTCC
...
Wir möchten jede der Dateien in
shell-lesson-data/exercise-data/creatures ändern, aber auch
eine Version der Originaldateien speichern. Wir wollen die
Originaldateien in neue Dateien mit den Namen
original-basilisk.dat und original-unicorn.dat
kopieren. Wir können nicht verwenden:
aus, denn das würde expandieren zu:
Dies würde unsere Dateien nicht sichern, stattdessen bekommen wir einen Fehler:
FEHLER
cp: target `original-*.dat' is not a directory
Dieses Problem tritt auf, wenn cp mehr als zwei Eingaben
erhält. Wenn das passiert, erwartet es, dass die letzte Eingabe ein
Verzeichnis ist, in das es alle Dateien kopieren kann, die ihm übergeben
wurden. Da es im Verzeichnis creatures kein Verzeichnis
namens original-*.dat gibt, erhalten wir einen Fehler.
Stattdessen können wir eine Schleife verwenden:
Diese Schleife führt den Befehl cp einmal für jeden
Dateinamen aus. Beim ersten Mal, wenn sich $filename zu
basilisk.dat ausdehnt, führt die Shell ihn aus:
Das zweite Mal lautet der Befehl:
Das dritte und letzte Mal lautet der Befehl:
Da der Befehl cp normalerweise keine Ausgabe erzeugt,
ist es schwer zu überprüfen, ob die Schleife korrekt funktioniert. Wir
haben jedoch bereits gelernt, wie man Zeichenketten mit
echo ausgibt, und wir können die Schleife so modifizieren,
dass sie echo verwendet, um unsere Befehle auszugeben, ohne
sie tatsächlich auszuführen. So können wir prüfen, welche Befehle in der
unveränderten Schleife ausgeführt werden würden.
Das folgende Diagramm zeigt, was passiert, wenn die geänderte
Schleife ausgeführt wird, und demonstriert, dass die vernünftige
Verwendung von echo eine gute Debugging-Technik ist.
{alt=“Die
for-Schleife”for filename in .dat; do echo cp \(filename original-\)filename;done” weist
der Variablen “$filename” nacheinander die Namen aller “.dat”-Dateien in
Ihrem aktuellen Verzeichnis zu und führt dann den Befehl aus. Mit den
Dateien “basilisk.dat”, “minotaur.dat” und “unicorn.dat” im aktuellen
Verzeichnis wird die Schleife nacheinander dreimal den Befehl echo
aufrufen und drei Zeilen ausgeben: “cp basislisk.dat
original-basilisk.dat”, dann “cp minotaur.datoriginal-minotaur.dat” und
schließlich “cp unicorn.datoriginal-unicorn.dat”“}
Nelle’s Pipeline: Verarbeitung von Dateien
Nelle ist nun bereit, ihre Datendateien mit Hilfe von
goostats.sh — einem von ihrem Betreuer geschriebenen
Shell-Skript zu verarbeiten. Dieses Skript berechnet einige Statistiken
aus einer Protein-Probendatei und nimmt zwei Argumente entgegen:
- eine Eingabedatei (die die Rohdaten enthält)
- eine Ausgabedatei (um die berechneten Statistiken zu speichern)
Da sie immer noch lernt, wie man die Shell benutzt, beschließt sie,
die benötigten Befehle schrittweise aufzubauen. Ihr erster Schritt ist
es, sicherzustellen, dass sie die richtigen Eingabedateien auswählen
kann — erinnern Sie sich, das sind diejenigen, deren Namen auf ‘A’ oder
‘B’ enden, und nicht auf ‘Z’. Nelle wechselt in das Verzeichnis
north-pacific-gyre und tippt:
BASH
$ cd
$ cd Desktop/shell-lesson-data/north-pacific-gyre
$ for datafile in NENE*A.txt NENE*B.txt
> do
> echo $datafile
> done
AUSGABE
NENE01729A.txt
NENE01736A.txt
NENE01751A.txt
...
NENE02040B.txt
NENE02043B.txt
Ihr nächster Schritt besteht darin, zu entscheiden, wie die Dateien
heißen sollen, die das Analyseprogramm goostats.sh
erstellen wird. Es scheint einfach zu sein, den Namen jeder Eingabedatei
mit “stats” voranzustellen, also modifiziert sie ihre Schleife, um dies
zu tun:
AUSGABE
NENE01729A.txt stats-NENE01729A.txt
NENE01736A.txt stats-NENE01729A.txt
NENE01751A.txt stats-NENE01729A.txt
...
NENE02040B.txt stats-NENE02040B.txt
NENE02043B.txt stats-NENE02043B.txt
Sie hat goostats.sh noch nicht wirklich ausgeführt, aber
jetzt ist sie sicher, dass sie die richtigen Dateien auswählen und die
richtigen Ausgabedateinamen erzeugen kann.
Das wiederholte Eingeben von Befehlen wird jedoch mühsam, und Nelle hat Angst, Fehler zu machen, also drückt sie, anstatt ihre Schleife erneut einzugeben, ↑. Daraufhin gibt die Shell die gesamte Schleife in einer Zeile wieder (mit Semikolons zur Trennung der Teile):
Mit Hilfe des ← navigiert Nelle zu dem Befehl
echo und ändert ihn in bash goostats.sh:
Wenn sie Enter drückt, führt die Shell den geänderten Befehl aus. Es scheint jedoch nichts zu passieren - es gibt keine Ausgabe. Nach einem Moment wird Nelle klar, dass sie, da ihr Skript nichts mehr auf dem Bildschirm ausgibt, keine Ahnung hat, ob es läuft, geschweige denn wie schnell. Sie beendet den laufenden Befehl, indem sie Strg+C eintippt, verwendet ↑, um den Befehl zu wiederholen, und ändert ihn so ab, dass er lautet:
BASH
$ for datafile in NENE*A.txt NENE*B.txt; do echo $datafile;
bash goostats.sh $datafile stats-$datafile; done
Anfang und Ende
Wir können an den Anfang einer Zeile in der Shell gehen, indem wir Strg+A eingeben und an das Ende mit Strg+E.
Wenn sie ihr Programm jetzt ausführt, produziert es alle fünf Sekunden oder so eine Zeile an Ausgabe:
AUSGABE
NENE01729A.txt
NENE01736A.txt
NENE01751A.txt
...
1518 mal 5 Sekunden, geteilt durch 60, sagt ihr, dass ihr Skript etwa
zwei Stunden für die Ausführung brauchen wird. Als letzte Kontrolle
öffnet sie ein weiteres Terminalfenster, geht in
north-pacific-gyre und benutzt
cat stats-NENE01729B.txt, um eine der Ausgabedateien zu
untersuchen. Es sieht gut aus, also beschließt sie, sich einen Kaffee zu
holen und ihre Lektüre fortzusetzen.
Diejenigen, die die “Geschichte” kennen, können wählen, sie zu wiederholen
Eine andere Möglichkeit, frühere Arbeiten zu wiederholen, ist die
Verwendung des Befehls history, um eine Liste der letzten
paar hundert Befehle zu erhalten, die ausgeführt wurden, und dann
!123 (wobei ‘123’ durch die Befehlsnummer ersetzt wird) zu
verwenden, um einen dieser Befehle zu wiederholen. Wenn Nelle zum
Beispiel dies tippt:
AUSGABE
456 for datafile in NENE*A.txt NENE*B.txt; do echo $datafile stats-$datafile; done
457 for datafile in NENE*A.txt NENE*B.txt; do echo $datafile stats-$datafile; done
458 for datafile in NENE*A.txt NENE*B.txt; do bash goostats.sh $datafile stats-$datafile; done
459 for datafile in NENE*A.txt NENE*B.txt; do echo $datafile; bash goostats.sh $datafile
stats-$datafile; done
460 history | tail -n 5
dann kann sie goostats.sh auf den Dateien erneut
ausführen, indem sie einfach !459 eingibt.
Andere History-Befehle
Es gibt eine Reihe anderer Kurzbefehle, um auf die Historie zuzugreifen.
- Strg+R schaltet in den History-Suchmodus ‘reverse-i-search’ und findet den letzten Befehl in Ihrer History, der mit dem Text übereinstimmt, den Sie als nächstes eingeben. Drücken Sie Strg+R ein oder mehrere Male, um nach früheren Übereinstimmungen zu suchen. Sie können dann mit der linken und rechten Pfeiltaste diese Zeile auswählen und bearbeiten und dann Return drücken, um den Befehl auszuführen.
-
!!ruft den unmittelbar vorhergehenden Befehl auf (Sie können dies bequemer finden als ↑) -
!$holt das letzte Wort des letzten Befehls. Das ist öfter nützlich als man denkt: nachbash goostats.sh NENE01729B.txt stats-NENE01729B.txtkann manless !$eingeben, um sich die Dateistats-NENE01729B.txtanzusehen, was schneller ist als ↑ und die Befehlszeile zu bearbeiten.
Durchführung eines Trockenlaufs
Eine Schleife ist eine Möglichkeit, viele Dinge auf einmal zu tun —
oder viele Fehler auf einmal zu machen, wenn sie das Falsche tut. Eine
Möglichkeit zu überprüfen, was eine Schleife tun würde, ist,
die Befehle, die sie ausführen würde, zu echo, anstatt sie
tatsächlich auszuführen.
Angenommen, wir wollen eine Vorschau auf die Befehle, die die folgende Schleife ausführen wird, ohne diese Befehle tatsächlich auszuführen:
Was ist der Unterschied zwischen den beiden Schleifen unten, und welche würden wir ausführen wollen?
Die zweite Version ist die, die wir ausführen wollen. Sie gibt alles,
was in den Anführungszeichen steht, auf dem Bildschirm aus, wobei der
Name der Schleifenvariablen erweitert wird, da wir ihm ein Dollarzeichen
vorangestellt haben. Sie verändert auch nicht die Datei
all.pdb, da >> wörtlich als Teil einer
Zeichenkette und nicht als Umleitungsanweisung behandelt wird.
Die erste Version hängt die Ausgabe des Befehls
echo cat $datafile an die Datei all.pdb an.
Diese Datei enthält nur die Liste; cat cubane.pdb,
cat ethane.pdb, cat methane.pdb usw.
Probieren Sie beide Versionen aus, um die Ausgabe zu sehen! Öffnen
Sie unbedingt die Datei all.pdb, um ihren Inhalt zu
sehen.
Verschachtelte Schleifen
Angenommen, wir wollen eine Verzeichnisstruktur einrichten, um einige Experimente zur Messung der Reaktionsgeschwindigkeitskonstanten mit verschiedenen Verbindungen und verschiedenen Temperaturen zu organisieren. Was wäre das Ergebnis des folgenden Codes:
Wir haben eine geschachtelte Schleife, d.h. innerhalb einer anderen Schleife, so dass für jede Art in der äußeren Schleife die innere Schleife (die geschachtelte Schleife) über die Liste der Temperaturen iteriert und für jede Kombination ein neues Verzeichnis erstellt.
Versuchen Sie, den Code selbst auszuführen, um zu sehen, welche Verzeichnisse erstellt werden!
- Eine
for-Schleife wiederholt die Befehle einmal für jedes Ding in einer Liste. - Jede
for-Schleife braucht eine Variable, die auf das Ding verweist, mit dem sie gerade arbeitet. - Verwenden Sie
$name, um eine Variable zu expandieren (d.h. ihren Wert zu erhalten). auch${name}kann verwendet werden. - Verwenden Sie keine Leerzeichen, Anführungszeichen oder Platzhalterzeichen wie ‘*’ oder ‘?’ in Dateinamen, da dies die Variablenexpansion erschwert.
- Geben Sie den Dateien konsistente Namen, die leicht mit Wildcard-Mustern übereinstimmen, um die Auswahl für die Schleife zu vereinfachen.
- Benutzen Sie die Pfeil-nach-oben-Taste, um durch die vorherigen Befehle zu blättern und sie zu bearbeiten und zu wiederholen.
- Verwenden Sie Strg+R, um die zuvor eingegebenen Befehle zu durchsuchen.
- Verwenden Sie
history, um die letzten Befehle anzuzeigen, und![number], um einen Befehl nach Nummer zu wiederholen.
Content from Shell-Skripte
Zuletzt aktualisiert am 2025-10-23 | Diese Seite bearbeiten
Übersicht
Fragen
- Wie kann ich Befehle speichern und wiederverwenden?
Ziele
- Schreiben Sie ein Shell-Skript, das einen Befehl oder eine Reihe von Befehlen für einen festen Satz von Dateien ausführt.
- Führen Sie ein Shell-Skript von der Kommandozeile aus.
- Schreiben Sie ein Shell-Skript, das mit einer Reihe von Dateien arbeitet, die der Benutzer auf der Kommandozeile definiert.
- Erstellen Sie Pipelines, die Shell-Skripte enthalten, die Sie und andere geschrieben haben.
Jetzt können wir endlich sehen, was die Shell zu einer so mächtigen Programmierumgebung macht. Wir werden die Befehle, die wir häufig wiederholen, in Dateien speichern, so dass wir alle diese Operationen später mit einem einzigen Befehl erneut ausführen können. Aus historischen Gründen wird ein Bündel von Befehlen, die in einer Datei gespeichert sind, gewöhnlich als Shell-Skript bezeichnet, aber täuschen Sie sich nicht — es sind eigentlich kleine Programme.
Durch das Schreiben von Shell-Skripten wird Ihre Arbeit nicht nur schneller, sondern Sie müssen auch nicht die gleichen Befehle immer wieder neu eingeben. Außerdem wird sie dadurch genauer (weniger Tippfehler) und reproduzierbarer. Wenn Sie später auf Ihre Arbeit zurückkommen (oder wenn jemand anderes Ihre Arbeit findet und darauf aufbauen möchte), können Sie die gleichen Ergebnisse reproduzieren, indem Sie einfach Ihr Skript ausführen, anstatt sich eine lange Liste von Befehlen zu merken oder neu einzugeben.
Beginnen wir damit, zu alkanes/ zurückzugehen und eine
neue Datei zu erstellen, middle.sh, die unser Shell-Skript
werden wird:
Der Befehl nano middle.sh öffnet die Datei
middle.sh mit dem Texteditor ‘nano’ (der in der Shell
läuft). Wenn die Datei nicht existiert, wird sie erstellt. Wir können
den Texteditor verwenden, um die Datei direkt zu bearbeiten, indem wir
die folgende Zeile einfügen:
head -n 15 octane.pdb | tail -n 5
Dies ist eine Variation der Pipe, die wir zuvor konstruiert haben und
die die Zeilen 11-15 der Datei octane.pdb auswählt.
Erinnern Sie sich daran, dass wir es noch nicht als Befehl
ausführen; wir binden die Befehle nur in eine Datei ein.
Dann speichern wir die Datei (Ctrl-O in nano) und
beenden den Texteditor (Ctrl-X in nano). Überprüfen Sie,
dass das Verzeichnis alkanes nun eine Datei namens
middle.sh enthält.
Nachdem wir die Datei gespeichert haben, können wir die Shell bitten,
die darin enthaltenen Befehle auszuführen. Unsere Shell heißt
bash, also führen wir den folgenden Befehl aus:
AUSGABE
ATOM 9 H 1 -4.502 0.681 0.785 1.00 0.00
ATOM 10 H 1 -5.254 -0.243 -0.537 1.00 0.00
ATOM 11 H 1 -4.357 1.252 -0.895 1.00 0.00
ATOM 12 H 1 -3.009 -0.741 -1.467 1.00 0.00
ATOM 13 H 1 -3.172 -1.337 0.206 1.00 0.00
Die Ausgabe unseres Skripts ist genau das, was wir erhalten würden, wenn wir die Pipeline direkt ausführen würden.
Text vs. Was auch immer
Normalerweise bezeichnen wir Programme wie Microsoft Word oder
LibreOffice Writer als “Texteditoren”, aber wir müssen etwas
vorsichtiger sein, wenn es um die Programmierung geht. Microsoft Word
verwendet standardmäßig .docx-Dateien, um nicht nur Text,
sondern auch Formatierungsinformationen über Schriftarten, Überschriften
und so weiter zu speichern. Diese zusätzlichen Informationen werden
nicht als Zeichen gespeichert und bedeuten nichts für Tools wie
head, das erwartet, dass Eingabedateien nur die Buchstaben,
Ziffern und Satzzeichen einer normalen Computertastatur enthalten. Wenn
Sie Programme bearbeiten, müssen Sie daher entweder einen reinen
Texteditor verwenden oder darauf achten, dass Sie Dateien als reinen
Text speichern.
Was, wenn wir Zeilen aus einer beliebigen Datei auswählen wollen? Wir
könnten jedes Mal middle.sh editieren, um den Dateinamen zu
ändern, aber das würde wahrscheinlich länger dauern, als den Befehl noch
einmal in der Shell einzugeben und ihn mit einem neuen Dateinamen
auszuführen. Lassen Sie uns stattdessen middle.sh editieren
und es vielseitiger machen:
Ersetzen Sie nun in “nano” den Text octane.pdb durch die
spezielle Variable namens $1:
head -n 15 "$1" | tail -n 5
Innerhalb eines Shell-Skripts bedeutet $1 “der erste
Dateiname (oder ein anderes Argument) in der Befehlszeile”. Wir können
unser Skript nun wie folgt ausführen:
AUSGABE
ATOM 9 H 1 -4.502 0.681 0.785 1.00 0.00
ATOM 10 H 1 -5.254 -0.243 -0.537 1.00 0.00
ATOM 11 H 1 -4.357 1.252 -0.895 1.00 0.00
ATOM 12 H 1 -3.009 -0.741 -1.467 1.00 0.00
ATOM 13 H 1 -3.172 -1.337 0.206 1.00 0.00
oder auf eine andere Datei wie diese:
AUSGABE
ATOM 9 H 1 1.324 0.350 -1.332 1.00 0.00
ATOM 10 H 1 1.271 1.378 0.122 1.00 0.00
ATOM 11 H 1 -0.074 -0.384 1.288 1.00 0.00
ATOM 12 H 1 -0.048 -1.362 -0.205 1.00 0.00
ATOM 13 H 1 -1.183 0.500 -1.412 1.00 0.00
Doppelte Anführungszeichen um Argumente
Aus demselben Grund, aus dem wir die Schleifenvariable in doppelte
Anführungszeichen setzen, umgeben wir $1 mit doppelten
Anführungszeichen, falls der Dateiname zufällig Leerzeichen enthält.
Derzeit müssen wir jedes Mal middle.sh bearbeiten, wenn
wir den Bereich der zurückgegebenen Zeilen anpassen wollen. Wir können
das ändern, indem wir unser Skript so konfigurieren, dass es stattdessen
drei Befehlszeilenargumente verwendet. Nach dem ersten
Kommandozeilenargument ($1) ist jedes weitere Argument, das
wir angeben, über die speziellen Variablen $1,
$2, $3 zugänglich, die sich jeweils auf das
erste, zweite und dritte Kommandozeilenargument beziehen.
Da wir dies wissen, können wir zusätzliche Argumente verwenden, um
den Bereich der Zeilen zu definieren, die an head bzw.
tail übergeben werden sollen:
head -n "$2" "$1" | tail -n "$3"
Wir können jetzt ausführen:
AUSGABE
ATOM 9 H 1 1.324 0.350 -1.332 1.00 0.00
ATOM 10 H 1 1.271 1.378 0.122 1.00 0.00
ATOM 11 H 1 -0.074 -0.384 1.288 1.00 0.00
ATOM 12 H 1 -0.048 -1.362 -0.205 1.00 0.00
ATOM 13 H 1 -1.183 0.500 -1.412 1.00 0.00
Indem wir die Argumente für unseren Befehl ändern, können wir das Verhalten unseres Skripts ändern:
AUSGABE
ATOM 14 H 1 -1.259 1.420 0.112 1.00 0.00
ATOM 15 H 1 -2.608 -0.407 1.130 1.00 0.00
ATOM 16 H 1 -2.540 -1.303 -0.404 1.00 0.00
ATOM 17 H 1 -3.393 0.254 -0.321 1.00 0.00
TER 18 1
Das funktioniert, aber es kann sein, dass die nächste Person, die
middle.sh liest, einen Moment braucht, um herauszufinden,
was es tut. Wir können unser Skript verbessern, indem wir einige
Kommentare am Anfang hinzufügen:
# Zeilen aus der Mitte einer Datei auswählen.
# Verwendung: bash middle.sh Dateiname Endzeile Anzahl_Zeilen
head -n "$2" "$1" | tail -n "$3"
Ein Kommentar beginnt mit einem #-Zeichen und läuft bis
zum Ende der Zeile. Der Computer ignoriert Kommentare, aber sie sind von
unschätzbarem Wert für das Verständnis und die Verwendung von Skripten
durch andere (auch durch Ihr zukünftiges Ich). Die einzige Einschränkung
ist, dass Sie jedes Mal, wenn Sie das Skript ändern, überprüfen sollten,
ob der Kommentar noch korrekt ist. Eine Erklärung, die den Leser in die
falsche Richtung lenkt, ist schlimmer als gar keine.
Was, wenn wir viele Dateien in einer einzigen Pipeline verarbeiten
wollen? Wenn wir zum Beispiel unsere .pdb-Dateien nach
Länge sortieren wollen, würden wir folgendes eingeben:
weil wc -l die Anzahl der Zeilen in den Dateien
auflistet (erinnern Sie sich, dass wc für ‘word count’
steht, das Hinzufügen der Option -l bedeutet stattdessen
‘count lines’) und sort -n die Dinge numerisch sortiert.
Wir könnten dies in eine Datei schreiben, aber dann würde es immer nur
eine Liste von .pdb Dateien im aktuellen Verzeichnis
sortieren. Wenn wir in der Lage sein wollen, eine sortierte Liste
anderer Arten von Dateien zu erhalten, brauchen wir einen Weg, um all
diese Namen in das Skript zu bekommen. Wir können nicht $1,
$2 und so weiter verwenden, weil wir nicht wissen, wie
viele Dateien es gibt. Stattdessen verwenden wir die spezielle Variable
$@, was soviel bedeutet wie ‘Alle Befehlszeilenargumente
für das Shell-Skript’. Wir sollten auch $@ in
Anführungszeichen setzen, um den Fall von Argumenten mit Leerzeichen zu
behandeln ("$@" ist eine spezielle Syntax und entspricht
"$1" "$2" …).
Hier ist ein Beispiel:
# Sort files by their length.
# Usage: bash sorted.sh one_or_more_filenames
wc -l "$@" | sort -n
AUSGABE
9 methane.pdb
12 ethane.pdb
15 propane.pdb
20 cubane.pdb
21 pentane.pdb
30 octane.pdb
163 ../creatures/basilisk.dat
163 ../creatures/minotaur.dat
163 ../creatures/unicorn.dat
596 total
Einzigartige Arten auflisten
Leah hat mehrere hundert Datendateien, von denen jede wie folgt formatiert ist:
2013-11-05,deer,5
2013-11-05,rabbit,22
2013-11-05,raccoon,7
2013-11-06,rabbit,19
2013-11-06,deer,2
2013-11-06,fox,1
2013-11-07,rabbit,18
2013-11-07,bear,1
Ein Beispiel für diesen Dateityp findet sich in
shell-lesson-data/exercise-data/animal-counts/animals.csv.
Wir können den Befehl
cut -d , -f 2 animals.csv | sort | uniq verwenden, um die
einzelnen Arten in animals.csv zu erzeugen. Um diese
Befehlsfolge nicht jedes Mal abtippen zu müssen, kann ein
Wissenschaftler stattdessen ein Shell-Skript schreiben.
Schreiben Sie ein Shell-Skript mit dem Namen species.sh,
das eine beliebige Anzahl von Dateinamen als Befehlszeilenargumente
annimmt und eine Variation des obigen Befehls verwendet, um eine Liste
der einzelnen Arten zu drucken, die in jeder dieser Dateien separat
vorkommen.
BASH
# Skript zum Auffinden einzigartiger Arten in CSV-Dateien, wobei „species“ das zweite Datenfeld ist.
# Dieses Skript akzeptiert eine beliebige Anzahl von Dateinamen als Befehlszeilenargumente.
# Über alle Dateien iterieren
for file in $@
do
echo "Einzigartige Arten in $file:"
# Artennamen extrahieren
cut -d , -f 2 $file | sort | uniq
done
Angenommen, wir haben gerade eine Reihe von Befehlen ausgeführt, die etwas Nützliches bewirkt haben - zum Beispiel die Erstellung eines Diagramms, das wir in einem Artikel verwenden möchten. Wir möchten das Diagramm später bei Bedarf erneut erstellen können, also wollen wir die Befehle in einer Datei speichern. Anstatt die Befehle erneut einzugeben (und sie möglicherweise falsch zu machen), können wir so vorgehen:
Die Datei redo-figure-3.sh enthält jetzt:
297 bash goostats.sh NENE01729B.txt stats-NENE01729B.txt
298 bash goodiff.sh stats-NENE01729B.txt /data/validated/01729.txt > 01729-differences.txt
299 cut -d ',' -f 2-3 01729-differences.txt > 01729-time-series.txt
300 ygraph --format scatter --color bw --borders none 01729-time-series.txt figure-3.png
301 history | tail -n 5 > redo-figure-3.sh
Nach kurzer Arbeit in einem Editor, um die fortlaufenden Nummern der
Befehle zu entfernen, und um die letzte Zeile zu entfernen, in der wir
den Befehl history aufgerufen haben, haben wir eine völlig
genaue Aufzeichnung, wie wir diese Figur erstellt haben.
Warum Befehle in der Historie aufzeichnen, bevor sie ausgeführt werden?
Wenn Sie den Befehl ausführen:
Der letzte Befehl in der Datei ist der history-Befehl
selbst, d.h. die Shell hat history zum Befehlsprotokoll
hinzugefügt, bevor sie ihn tatsächlich ausführt. Tatsächlich fügt die
Shell immer Befehle in das Protokoll ein, bevor sie ausgeführt
werden. Warum, glauben Sie, tut sie das?
Wenn ein Befehl zu einem Absturz oder einem Hänger führt, könnte es nützlich sein, zu wissen, was dieser Befehl war, um das Problem zu untersuchen. Würde der Befehl erst nach seiner Ausführung aufgezeichnet werden, hätten wir im Falle eines Absturzes keine Aufzeichnung des zuletzt ausgeführten Befehls.
In der Praxis entwickeln die meisten Leute Shell-Skripte, indem sie
Befehle an der Shell-Eingabeaufforderung ein paar Mal ausführen, um
sicherzustellen, dass sie das Richtige tun, und sie dann zur
Wiederverwendung in einer Datei speichern. Diese Arbeitsweise ermöglicht
es den Leuten, das, was sie über ihre Daten und ihren Arbeitsablauf
herausgefunden haben, mit einem Aufruf von history und ein
wenig Bearbeitung zu recyceln, um die Ausgabe zu bereinigen und als
Shell-Skript zu speichern.
Nelle’s Pipeline: Erstellen eines Skripts
Nelles Vorgesetzter bestand darauf, dass alle ihre Analysen reproduzierbar sein müssen. Am einfachsten ist es, alle Schritte in einem Skript festzuhalten.
Zuerst kehren wir in Nelles Projektverzeichnis zurück:
Sie erstellt eine Datei mit nano …
…die folgendes enthält:
BASH
# Berechnen Sie Statistiken für Datendateien.
for datafile in "$@"
do
echo $datafile
bash goostats.sh $datafile stats-$datafile
done
Sie speichert dies in einer Datei mit dem Namen
do-stats.sh, so dass sie nun die erste Stufe ihrer Analyse
wiederholen kann, indem sie eingibt:
Sie kann auch dies tun:
so dass die Ausgabe nur die Anzahl der verarbeiteten Dateien ist und nicht die Namen der verarbeiteten Dateien.
Eine Sache, die man bei Nelles Skript beachten sollte, ist, dass es die Person, die es ausführt, entscheiden lässt, welche Dateien verarbeitet werden sollen. Sie hätte es auch so schreiben können:
BASH
# Berechnen Sie die Statistiken für die Datendateien von Standort A und Standort B.
for datafile in NENE*A.txt NENE*B.txt
do
echo $datafile
bash goostats.sh $datafile stats-$datafile
done
Der Vorteil ist, dass dabei immer die richtigen Dateien ausgewählt
werden: Sie muss nicht daran denken, die “Z”-Dateien auszuschließen. Der
Nachteil ist, dass es immer nur diese Dateien auswählt — sie
kann es nicht auf alle Dateien (einschließlich der ‘Z’-Dateien) oder auf
die ‘G’- oder ‘H’-Dateien anwenden, die ihre Kollegen in der Antarktis
produzieren, ohne das Skript zu bearbeiten. Wenn sie etwas
abenteuerlicher sein wollte, könnte sie ihr Skript so ändern, dass es
nach Befehlszeilenargumenten sucht und
NENE*A.txt NENE*B.txt verwendet, wenn keine angegeben
wurden. Natürlich führt dies zu einem weiteren Kompromiss zwischen
Flexibilität und Komplexität.
Variablen in Shell-Skripten
Stellen Sie sich vor, Sie haben im Verzeichnis alkanes
ein Shell-Skript namens script.sh, das die folgenden
Befehle enthält:
Während du dich im Verzeichnis alkanes befindest, gibst
du den folgenden Befehl ein:
Welche der folgenden Ausgaben würden Sie erwarten?
- Alle Zeilen zwischen der ersten und der letzten Zeile jeder Datei,
die auf
.pdbim Verzeichnisalkanesendet - Die erste und die letzte Zeile jeder Datei, die auf
.pdbim Verzeichnisalkanesendet - Die erste und die letzte Zeile jeder Datei im Verzeichnis
alkanes - Ein Fehler wegen der Anführungszeichen um
*.pdb
Die richtige Antwort ist 2.
Die speziellen Variablen $1, $2 und
$3 stehen für die Kommandozeilenargumente, die dem Skript
übergeben werden, so dass die Befehle ausgeführt werden:
BASH
$ head -n 1 cubane.pdb ethane.pdb octane.pdb pentane.pdb propane.pdb
$ tail -n 1 cubane.pdb ethane.pdb octane.pdb pentane.pdb propane.pdb
Die Shell expandiert '*.pdb' nicht, weil es von
Anführungszeichen eingeschlossen ist. Das erste Argument des Skripts ist
also '*.pdb', das innerhalb des Skripts durch
head und tail erweitert wird.
Finde die längste Datei mit einer gegebenen Erweiterung
Schreiben Sie ein Shell-Skript mit dem Namen longest.sh,
das den Namen eines Verzeichnisses und eine Dateinamenserweiterung als
Argumente annimmt und den Namen der Datei mit den meisten Zeilen in
diesem Verzeichnis mit dieser Erweiterung ausgibt. Zum Beispiel:
würde den Namen der Datei .pdb in
shell-lesson-data/exercise-data/alkanes ausgeben, die die
meisten Zeilen hat.
Sie können Ihr Skript auch in einem anderen Verzeichnis testen, z.B.
BASH
# Shell-Skript, das zwei Argumente akzeptiert:
# 1. einen Verzeichnisnamen
# 2. eine Dateierweiterung
# und den Namen der Datei in diesem Verzeichnis ausgibt,
# die die meisten Zeilen enthält, die mit der Dateierweiterung übereinstimmen.
wc -l $1/*.$2 | sort -n | tail -n 2 | head -n 1
Der erste Teil der Pipeline, wc -l $1/*.$2 | sort -n,
zählt die Zeilen in jeder Datei und sortiert sie numerisch (die größte
zuletzt). Wenn es mehr als eine Datei gibt, gibt wc auch
eine abschließende Übersichtszeile aus, die die Gesamtzahl der Zeilen in
allen Dateien angibt. Wir benutzen
tail -n 2 | head -n 1, um diese letzte Zeile zu
verwerfen.
Mit wc -l $1/*.$2 | sort -n | tail -n 1 sehen wir die
abschließende Zusammenfassungszeile: wir können unsere Pipeline
stückweise aufbauen, um sicher zu sein, dass wir die Ausgabe
verstehen.
Skript Leseverstehen
Für diese Frage betrachten wir noch einmal das Verzeichnis
shell-lesson-data/exercise-data/alkanes. Dieses enthält
eine Reihe von .pdb-Dateien zusätzlich zu allen anderen
Dateien, die Sie erstellt haben. Erkläre, was jedes der folgenden drei
Skripte tun würde, wenn es als bash script1.sh *.pdb,
bash script2.sh *.pdb bzw.
bash script3.sh *.pdb ausgeführt würde.
In jedem Fall expandiert die Shell den Platzhalter in
*.pdb, bevor sie die resultierende Liste von Dateinamen als
Argumente an das Skript weitergibt.
Skript 1 würde eine Liste aller Dateien ausgeben, die einen Punkt in ihrem Namen enthalten. Die Argumente, die dem Skript übergeben werden, werden im Skript selbst nicht verwendet.
Skript 2 würde den Inhalt der ersten 3 Dateien mit der
Dateierweiterung .pdb ausgeben.$1,
$2 und $3 beziehen sich jeweils auf das erste,
zweite und dritte Argument.
Skript 3 würde alle Argumente für das Skript ausgeben (d.h. alle
.pdb-Dateien), gefolgt von
.pdb.$@ bezieht sich auf alle
Argumente, die einem Shell-Skript übergeben werden.
AUSGABE
cubane.pdb ethane.pdb methane.pdb octane.pdb pentane.pdb propane.pdb.pdb
Debugging-Skripte
Angenommen, Sie haben das folgende Skript in einer Datei namens
do-errors.sh im Verzeichnis north-pacific-gyre
von Nelle gespeichert:
BASH
# Berechnen Sie Statistiken für Datendateien.
for datafile in "$@"
do
echo $datfile
bash goostats.sh $datafile stats-$datafile
done
Wenn Sie es aus dem Verzeichnis north-pacific-gyre
ausführen:
Die Ausgabe ist leer. Um herauszufinden, warum, führen Sie das Skript
mit der Option -x erneut aus:
Was zeigt Ihnen die Ausgabe? Welche Zeile ist für den Fehler verantwortlich?
Die Option -x bewirkt, dass bash im
Debug-Modus läuft. Dadurch wird jeder Befehl während seiner Ausführung
ausgedruckt, was Ihnen hilft, Fehler zu finden. In diesem Beispiel
können wir sehen, dass echo nichts ausgibt. Wir haben einen
Tippfehler im Namen der Schleifenvariablen gemacht, und die Variable
datfile existiert nicht und gibt daher einen leeren String
zurück.
- Speichern Sie Befehle in Dateien (normalerweise Shell-Skripte genannt) zur Wiederverwendung.
-
bash [filename]führt die in einer Datei gespeicherten Befehle aus. -
$@bezieht sich auf alle Kommandozeilenargumente eines Shell-Skripts. -
$1,$2, etc. beziehen sich auf das erste Kommandozeilenargument, das zweite Kommandozeilenargument, etc. - Setzen Sie Variablen in Anführungszeichen, wenn die Werte Leerzeichen enthalten könnten.
- Dem Benutzer die Entscheidung zu überlassen, welche Dateien verarbeitet werden sollen, ist flexibler und konsistenter mit eingebauten Unix-Befehlen.
Content from Dinge finden
Zuletzt aktualisiert am 2025-10-23 | Diese Seite bearbeiten
Übersicht
Fragen
- Wie kann ich Dateien finden?
- Wie kann ich Dinge in Dateien finden?
Ziele
- Verwenden Sie
grep, um Zeilen aus Textdateien auszuwählen, die einfachen Mustern entsprechen. - Verwenden Sie
find, um Dateien und Verzeichnisse zu finden, deren Namen einfachen Mustern entsprechen. - Verwenden Sie die Ausgabe eines Befehls als Befehlszeilenargument(e) für einen anderen Befehl.
- Erläutern Sie, was mit “Text”- und “Binär”-Dateien gemeint ist und warum viele gängige Werkzeuge mit letzteren nicht gut umgehen können.
Genauso wie viele von uns heute “Google” als Verb für “finden” verwenden, benutzen Unix-Programmierer oft das Wort “grep”. grep” ist eine Abkürzung für “global/regulärer Ausdruck/Druck”, eine übliche Abfolge von Operationen in frühen Unix-Texteditoren. Es ist auch der Name eines sehr nützlichen Befehlszeilenprogramms.
grep findet und druckt Zeilen in Dateien, die einem
Muster entsprechen. Für unsere Beispiele verwenden wir eine Datei, die
drei Haiku aus einem [1998er Wettbewerb] (https://web.archive.org/web/19991201042211/http://salon.com/21st/chal/1998/01/26chal.html)
in der Zeitschrift Salon enthält (Dank an die Autoren Bill
Torcaso, Howard Korder bzw. Margaret Segall. Siehe Haiku-Fehlermeldungen
im Archiv Seite
1 und Seite
2 .). Für diese Reihe von Beispielen arbeiten wir im
Unterverzeichnis writing:
AUSGABE
The Tao that is seen
Is not the true Tao, until
You bring fresh toner.
With searching comes loss
and the presence of absence:
"My Thesis" not found.
Yesterday it worked
Today it is not working
Software is like that.
Suchen wir nach Zeilen, die das Wort “not” enthalten:
AUSGABE
Is not the true Tao, until
"My Thesis" not found
Today it is not working
Hier ist not das Muster, nach dem wir suchen. Der Befehl
grep durchsucht die Datei nach Übereinstimmungen mit dem angegebenen
Muster. Geben Sie dazu grep ein, dann das gesuchte Muster
und schließlich den Namen der Datei (oder der Dateien), in der Sie
suchen.
Ausgegeben werden die drei Zeilen der Datei, die die Buchstaben “not” enthalten.
Standardmäßig sucht grep nach einem Muster unter Berücksichtigung der Groß- und Kleinschreibung. Außerdem muss das von uns gewählte Suchmuster kein vollständiges Wort bilden, wie wir im nächsten Beispiel sehen werden.
Suchen wir nach dem Muster: ‘The’.
AUSGABE
The Tao that is seen
"My Thesis" not found.
Diesmal werden zwei Zeilen ausgegeben, die die Buchstaben “The” enthalten, von denen eine unser Suchmuster innerhalb eines größeren Wortes, “Thesis”, enthält.
Um Übereinstimmungen auf Zeilen zu beschränken, die das Wort “The”
allein enthalten, können wir grep die Option
-w geben. Dadurch werden die Treffer auf Wortgrenzen
beschränkt.
Später in dieser Lektion werden wir auch sehen, wie wir das Suchverhalten von grep in Bezug auf die Groß- und Kleinschreibung ändern können.
AUSGABE
The Tao that is seen
Beachten Sie, dass eine “Wortgrenze” den Anfang und das Ende einer
Zeile umfasst, also nicht nur von Leerzeichen umgebene Buchstaben.
Manchmal wollen wir nicht nach einem einzelnen Wort suchen, sondern nach
einer Phrase. Wir können dies auch mit grep tun, indem wir
die Phrase in Anführungszeichen setzen.
AUSGABE
Today it is not working
Wir haben jetzt gesehen, dass Sie einzelne Wörter nicht in Anführungszeichen setzen müssen, aber es ist nützlich, Anführungszeichen zu verwenden, wenn Sie nach mehreren Wörtern suchen. Dies erleichtert auch die Unterscheidung zwischen dem Suchbegriff oder der Phrase und der gesuchten Datei. In den folgenden Beispielen werden wir Anführungszeichen verwenden.
Eine weitere nützliche Option ist -n, die die
übereinstimmenden Zeilen nummeriert:
AUSGABE
5:With searching comes loss
9:Yesterday it worked
10:Today it is not working
Hier ist zu erkennen, dass die Zeilen 5, 9 und 10 die Buchstaben “it” enthalten.
Wir können Optionen (d.h. Flags) wie bei anderen Unix-Befehlen
kombinieren. Wir wollen zum Beispiel die Zeilen finden, die das Wort
“the” enthalten. Wir können die Option -w kombinieren, um
die Zeilen zu finden, die das Wort ‘the’ enthalten, und -n,
um die entsprechenden Zeilen zu nummerieren:
AUSGABE
2:Is not the true Tao, until
6:and the presence of absence:
Jetzt wollen wir die Option -i verwenden, um die Groß-
und Kleinschreibung zu ignorieren:
AUSGABE
1:The Tao that is seen
2:Is not the true Tao, until
6:and the presence of absence:
Jetzt wollen wir die Option -v verwenden, um unsere
Suche zu invertieren, d.h. wir wollen die Zeilen ausgeben, die das Wort
‘the’ nicht enthalten.
AUSGABE
1:The Tao that is seen
3:You bring fresh toner.
4:
5:With searching comes loss
7:"My Thesis" not found.
8:
9:Yesterday it worked
10:Today it is not working
11:Software is like that.
Wenn wir die Option -r (rekursiv) verwenden, kann
grep rekursiv in einer Menge von Dateien in
Unterverzeichnissen nach einem Muster suchen.
Lassen Sie uns rekursiv nach Yesterday im Verzeichnis
shell-lesson-data/exercise-data/writing suchen:
AUSGABE
./LittleWomen.txt:"Yesterday, when Aunt was asleep and I was trying to be as still as a
./LittleWomen.txt:Yesterday at dinner, when an Austrian officer stared at us and then
./LittleWomen.txt:Yesterday was a quiet day spent in teaching, sewing, and writing in my
./haiku.txt:Yesterday it worked
grep hat viele andere Optionen. Um herauszufinden,
welche das sind, können wir sie eingeben:
AUSGABE
Usage: grep [OPTION]... PATTERN [FILE]...
Search for PATTERN in each FILE or standard input.
PATTERN is, by default, a basic regular expression (BRE).
Example: grep -i 'hello world' menu.h main.c
Regexp selection and interpretation:
-E, --extended-regexp PATTERN is an extended regular expression (ERE)
-F, --fixed-strings PATTERN is a set of newline-separated fixed strings
-G, --basic-regexp PATTERN is a basic regular expression (BRE)
-P, --perl-regexp PATTERN is a Perl regular expression
-e, --regexp=PATTERN use PATTERN for matching
-f, --file=FILE obtain PATTERN from FILE
-i, --ignore-case ignore case distinctions
-w, --word-regexp force PATTERN to match only whole words
-x, --line-regexp force PATTERN to match only whole lines
-z, --null-data a data line ends in 0 byte, not newline
Miscellaneous:
... ... ...
Verwendung von grep
Welcher Befehl würde zu der folgenden Ausgabe führen:
AUSGABE
and the presence of absence:
grep "of" haiku.txtgrep -E "of" haiku.txtgrep -w "of" haiku.txtgrep -i "of" haiku.txt
Die richtige Antwort ist 3, denn die Option -w sucht nur
nach Übereinstimmungen mit ganzen Wörtern. Die anderen Optionen passen
auch auf “of”, wenn es Teil eines anderen Wortes ist.
Wildcards
Die eigentliche Stärke von grep liegt jedoch nicht in
den Optionen, sondern in der Tatsache, dass Muster Platzhalter enthalten
können. (Der technische Name dafür ist reguläre
Ausdrücke, wofür das “re” in “grep” steht.) Reguläre Ausdrücke
sind sowohl komplex als auch mächtig; wenn Sie komplexe Suchvorgänge
durchführen wollen, sehen Sie sich bitte die Lektion auf unserer
Website an. Als Kostprobe können wir Zeilen finden, die ein ‘o’ an
der zweiten Stelle haben, etwa so:
AUSGABE
You bring fresh toner.
Today it is not working
Software is like that.
Wir benutzen die Option -E und setzen das Muster in
Anführungszeichen, um zu verhindern, dass die Shell versucht, es zu
interpretieren. (Wenn das Muster zum Beispiel ein *
enthielte, würde die Shell versuchen, es zu expandieren, bevor sie
grep ausführt.) Das ^ im Muster verankert die
Übereinstimmung am Anfang der Zeile. Das . passt auf ein
einzelnes Zeichen (genau wie ? in der Shell), während das
o auf ein tatsächliches ‘o’ passt.
Nachverfolgung einer Spezies
Leah hat mehrere hundert Datendateien in einem Verzeichnis gespeichert, von denen jede wie folgt formatiert ist:
2012-11-05,deer,5
2012-11-05,rabbit,22
2012-11-05,raccoon,7
2012-11-06,rabbit,19
2012-11-06,deer,2
2012-11-06,fox,4
2012-11-07,rabbit,16
2012-11-07,bear,1
Sie möchte ein Shell-Skript schreiben, das eine Spezies als erstes
Befehlszeilenargument und ein Verzeichnis als zweites Argument annimmt.
Das Skript soll eine Datei mit dem Namen
<species>.txt zurückgeben, die eine Liste von Daten
und die Anzahl der an jedem Datum beobachteten Arten enthält. Bei
Verwendung der oben gezeigten Daten würde rabbit.txt zum
Beispiel enthalten:
2012-11-05,22
2012-11-06,19
2012-11-07,16
Nachfolgend enthält jede Zeile einen einzelnen Befehl, eine Pipe. Ordnen Sie deren Reihenfolge in einem Befehl an, um das Ziel von Leah zu erreichen:
Hinweis: Verwenden Sie man grep, um zu suchen, wie man
Text in einem Verzeichnis rekursiv einfängt und man cut, um
mehr als ein Feld in einer Zeile auszuwählen.
Ein Beispiel für eine solche Datei ist in
shell-lesson-data/exercise-data/animal-counts/animals.csv
enthalten
grep -w $1 -r $2 | cut -d : -f 2 | cut -d , -f 1,3 > $1.txt
Sie können die Reihenfolge der beiden Cut-Befehle vertauschen und es funktioniert trotzdem. Versuchen Sie in der Befehlszeile, die Reihenfolge der Schnittbefehle zu ändern, und sehen Sie sich die Ausgabe der einzelnen Schritte an, um zu sehen, warum dies der Fall ist.
Sie würden das obige Skript wie folgt aufrufen:
Little Women
Sie und Ihr Freund, der gerade Little Women von Louisa May
Alcott gelesen hat, streiten sich. Von den vier Schwestern im Buch, Jo,
Meg, Beth und Amy, meint Ihr Freund, dass Jo am meisten erwähnt wurde.
Sie hingegen sind sich sicher, dass es Amy war. Glücklicherweise haben
Sie eine Datei LittleWomen.txt, die den vollständigen Text
des Romans enthält
(shell-lesson-data/exercise-data/writing/LittleWomen.txt).
Wie würden Sie mit Hilfe einer for-Schleife die Anzahl der
Erwähnungen jeder der vier Schwestern tabellarisch darstellen?
Hinweis: Eine Lösung könnte die Befehle grep und
wc und ein | verwenden, während eine andere
die Optionen grep nutzt. Es gibt oft mehr als einen Weg,
eine Programmieraufgabe zu lösen, so dass eine bestimmte Lösung in der
Regel auf der Grundlage einer Kombination von korrektem Ergebnis,
Eleganz, Lesbarkeit und Geschwindigkeit gewählt wird.
for sis in Jo Meg Beth Amy
do
echo $sis:
grep -ow $sis LittleWomen.txt | wc -l
done
Alternative, etwas schlechtere Lösung:
for sis in Jo Meg Beth Amy
do
echo $sis:
grep -ocw $sis LittleWomen.txt
done
Diese Lösung ist minderwertig, weil grep -c nur die
Anzahl der übereinstimmenden Zeilen meldet. Die Gesamtzahl der
Übereinstimmungen, die von dieser Methode gemeldet wird, ist geringer,
wenn es mehr als eine Übereinstimmung pro Zeile gibt.
Aufmerksamen Beobachtern ist vielleicht aufgefallen, dass die Namen
der Figuren in den Kapiteltiteln manchmal in Großbuchstaben erscheinen
(z.B. ‘MEG GOES TO VANITY FAIR’). Wenn Sie auch diese mitzählen wollten,
könnten Sie die Option -i zur Unterscheidung der Groß- und
Kleinschreibung hinzufügen (obwohl dies in diesem Fall keinen Einfluss
auf die Antwort auf die Frage hat, welche Schwester am häufigsten
erwähnt wird).
Während grep Zeilen in Dateien findet, findet der Befehl
find die Dateien selbst. Auch hier gibt es eine Menge
Optionen; um zu zeigen, wie die einfachsten funktionieren, verwenden wir
den unten gezeigten
shell-lesson-data/exercise-data-Verzeichnisbaum.
AUSGABE
.
├── animal-counts/
│ └── animals.csv
├── creatures/
│ ├── basilisk.dat
│ ├── minotaur.dat
│ └── unicorn.dat
├── numbers.txt
├── alkanes/
│ ├── cubane.pdb
│ ├── ethane.pdb
│ ├── methane.pdb
│ ├── octane.pdb
│ ├── pentane.pdb
│ └── propane.pdb
└── writing/
├── haiku.txt
└── LittleWomen.txt
Das Verzeichnis exercise-data enthält eine Datei,
numbers.txt und vier Verzeichnisse:
animal-counts, creatures, alkanes
und writing mit verschiedenen Dateien.
Für unseren ersten Befehl führen wir find . aus (denken
Sie daran, diesen Befehl aus dem Ordner
shell-lesson-data/exercise-data auszuführen).
AUSGABE
.
./writing
./writing/LittleWomen.txt
./writing/haiku.txt
./creatures
./creatures/basilisk.dat
./creatures/unicorn.dat
./creatures/minotaur.dat
./animal-counts
./animal-counts/animals.csv
./numbers.txt
./alkanes
./alkanes/ethane.pdb
./alkanes/propane.pdb
./alkanes/octane.pdb
./alkanes/pentane.pdb
./alkanes/methane.pdb
./alkanes/cubane.pdb
Wie immer steht . für das aktuelle Arbeitsverzeichnis,
in dem wir unsere Suche beginnen wollen. die Ausgabe von
find sind die Namen aller Dateien und
Verzeichnisse unterhalb des aktuellen Arbeitsverzeichnisses. Das mag
zunächst nutzlos erscheinen, aber find hat viele
Möglichkeiten, die Ausgabe zu filtern, und in dieser Lektion werden wir
einige davon kennenlernen.
Die erste Option in unserer Liste ist -type d, was
“Dinge, die Verzeichnisse sind” bedeutet. Sicherlich ist die Ausgabe von
find die Namen der fünf Verzeichnisse (einschließlich
.):
AUSGABE
.
./writing
./creatures
./animal-counts
./alkanes
Beachten Sie, dass die Objekte, die find findet, nicht
in einer bestimmten Reihenfolge aufgelistet sind. Wenn wir
-type d in -type f ändern, erhalten wir
stattdessen eine Auflistung aller Dateien:
AUSGABE
./writing/LittleWomen.txt
./writing/haiku.txt
./creatures/basilisk.dat
./creatures/unicorn.dat
./creatures/minotaur.dat
./animal-counts/animals.csv
./numbers.txt
./alkanes/ethane.pdb
./alkanes/propane.pdb
./alkanes/octane.pdb
./alkanes/pentane.pdb
./alkanes/methane.pdb
./alkanes/cubane.pdb
Versuchen wir nun, nach Namen zu suchen:
AUSGABE
./numbers.txt
Wir haben erwartet, dass es alle Textdateien findet, aber es gibt nur
./numbers.txt aus. Das Problem ist, dass die Shell
Platzhalterzeichen wie * vor der Ausführung von
Befehlen expandiert. Da *.txt im aktuellen Verzeichnis zu
./numbers.txt expandiert, war der Befehl, den wir
tatsächlich ausgeführt haben:
find hat getan, worum wir gebeten haben; wir haben nur
nach der falschen Sache gefragt.
Um das zu bekommen, was wir wollen, machen wir es wie bei
grep: Wir setzen *.txt in Anführungszeichen,
um zu verhindern, dass die Shell den Platzhalter *
erweitert. Auf diese Weise erhält find tatsächlich das
Muster *.txt, nicht den erweiterten Dateinamen
numbers.txt:
AUSGABE
./writing/LittleWomen.txt
./writing/haiku.txt
./numbers.txt
Auflistung vs. Auffinden
ls und find können mit den richtigen
Optionen ähnliche Dinge tun, aber unter normalen Umständen listet
ls alles auf, was es kann, während find nach
Dingen mit bestimmten Eigenschaften sucht und sie anzeigt.
Wie wir bereits gesagt haben, liegt die Stärke der Kommandozeile in
der Kombination von Werkzeugen. Wir haben gesehen, wie man das mit Pipes
macht; sehen wir uns eine andere Technik an. Wie wir gerade gesehen
haben, gibt uns find . -name "*.txt" eine Liste aller
Textdateien im oder unterhalb des aktuellen Verzeichnisses. Wie können
wir das mit wc -l kombinieren, um die Zeilen in all diesen
Dateien zu zählen?
Am einfachsten ist es, den Befehl find in
$() einzufügen:
AUSGABE
21022 ./writing/LittleWomen.txt
11 ./writing/haiku.txt
5 ./numbers.txt
21038 total
Wenn die Shell diesen Befehl ausführt, führt sie als erstes das aus,
was in $() steht. Dann ersetzt sie den Ausdruck
$() durch die Ausgabe dieses Befehls. Da die Ausgabe von
find aus den drei Dateinamen
./writing/LittleWomen.txt, ./writing/haiku.txt
und ./numbers.txt besteht, konstruiert die Shell den
Befehl:
das ist das, was wir wollten. Diese Expansion ist genau das, was die
Shell macht, wenn sie Platzhalter wie * und ?
expandiert, aber wir können jeden beliebigen Befehl als unseren eigenen
“Platzhalter” verwenden.
Es ist sehr üblich, find und grep zusammen
zu verwenden. Die erste findet Dateien, die einem Muster entsprechen;
die zweite sucht nach Zeilen innerhalb dieser Dateien, die einem anderen
Muster entsprechen. Hier können wir zum Beispiel txt-Dateien finden, die
das Wort “searching” enthalten, indem wir nach der Zeichenfolge
“searching” in allen .txt-Dateien im aktuellen Verzeichnis
suchen:
AUSGABE
./writing/LittleWomen.txt:sitting on the top step, affected to be searching for her book, but was
./writing/haiku.txt:With searching comes loss
Abgleichen und Subtrahieren
Die Option -v zu grep kehrt den
Mustervergleich um, so dass nur Zeilen gedruckt werden, die
nicht dem Muster entsprechen. Welcher der folgenden Befehle
findet dann alle .dat-Dateien in creatures außer
unicorn.dat? Sobald Sie sich Ihre Antwort überlegt haben,
können Sie die Befehle im Verzeichnis
shell-lesson-data/exercise-data testen.
find creatures -name "*.dat" | grep -v unicornfind creatures -name *.dat | grep -v unicorngrep -v "unicorn" $(find creatures -name "*.dat")- Keines der oben genannten.
Option 1 ist richtig. Das Einschließen des Vergleichsausdrucks in
Anführungszeichen verhindert, dass die Shell ihn expandiert, so dass er
an den Befehl find übergeben wird.
Option 2 funktioniert auch in diesem Fall, weil die Shell versucht,
*.dat zu expandieren, aber es gibt keine *.dat
Dateien im aktuellen Verzeichnis, also wird der Platzhalterausdruck an
find übergeben. Wir haben dies zum ersten Mal in Episode 3 gesehen.
Option 3 ist falsch, weil sie den Inhalt der Dateien nach Zeilen durchsucht, die nicht mit “unicorn” übereinstimmen, anstatt die Dateinamen zu durchsuchen.
Binäre Dateien
Wir haben uns ausschließlich auf die Suche nach Mustern in Textdateien konzentriert. Was ist, wenn Ihre Daten als Bilder, in Datenbanken oder in einem anderen Format gespeichert sind?
Eine Handvoll Werkzeuge erweitern grep, um einige
Nicht-Text-Formate zu verarbeiten. Ein verallgemeinerbarerer Ansatz
besteht jedoch darin, die Daten in Text zu konvertieren oder die
textähnlichen Elemente aus den Daten zu extrahieren. Einerseits sind
damit einfache Dinge leicht zu erledigen. Auf der anderen Seite sind
komplexe Dinge in der Regel unmöglich. Es ist zum Beispiel einfach
genug, ein Programm zu schreiben, das X- und Y-Maße aus Bilddateien
extrahiert, um damit zu spielen, aber wie würden Sie etwas schreiben, um
Werte in einem Arbeitsblatt zu finden, dessen Zellen Formeln
enthalten?
Eine letzte Möglichkeit ist, zu erkennen, dass die Shell und die Textverarbeitung ihre Grenzen haben, und eine andere Programmiersprache zu verwenden. Wenn es an der Zeit ist, dies zu tun, seien Sie nicht zu streng mit der Shell. Viele moderne Programmiersprachen haben viele Ideen von ihr übernommen, und Nachahmung ist auch die schönste Form des Lobes.
Die Unix-Shell ist älter als die meisten Menschen, die sie benutzen. Sie hat so lange überlebt, weil sie eine der produktivsten Programmierumgebungen ist, die je geschaffen wurden — vielleicht sogar die produktivste. Ihre Syntax mag kryptisch sein, aber wer sie beherrscht, kann interaktiv mit verschiedenen Befehlen experimentieren und dann das Gelernte zur Automatisierung seiner Arbeit nutzen. Grafische Benutzeroberflächen mögen anfangs einfacher zu bedienen sein, aber einmal gelernt, ist die Produktivität der Shell unschlagbar. Und wie Alfred North Whitehead 1911 schrieb: “Die Zivilisation schreitet voran, indem sie die Zahl der wichtigen Operationen erweitert, die wir ausführen können, ohne darüber nachzudenken
- Sucht alle Dateien mit der Erweiterung
.datrekursiv im aktuellen Verzeichnis - Zählen Sie die Anzahl der Zeilen, die jede dieser Dateien enthält
- Sortieren Sie die Ausgabe aus Schritt 2. numerisch
-
findfindet Dateien mit bestimmten Eigenschaften, die den Mustern entsprechen. -
grepwählt Zeilen in Dateien aus, die dem Muster entsprechen. -
--helpist eine Option, die von vielen Bash-Befehlen und Programmen unterstützt wird, die aus der Bash heraus ausgeführt werden können, um weitere Informationen über die Verwendung dieser Befehle oder Programme anzuzeigen. -
man [command]zeigt die Handbuchseite für einen bestimmten Befehl an. -
$([command])fügt die Ausgabe eines Befehls an dieser Stelle ein.