bash_2

Suchen, Reguläre Ausdrücke, Variablen etc.

Einstieg in die Bash-Shell - Teil 2

Lernziele:

  • Erlernen, wie Dateien nach verschiedenen Kriterien gefunden werden können.
  • Kennenlernen von regulären Ausdrücken.
  • Kennenlernen von Variablen
  • Kennenlernen von Substitutionen
  • Kennenlernen von Subshells

Cheatsheets

Hinweis: Da die Benutzung der Bash teilweise kryptisch und die Syntax schwer zu merken ist, können Sie Cheatsheets für die Übungen etc. verwenden:

Hier finden Sie eine Liste der GNU Core Utils.

Suchen

find

Mit Hilfe von find können Sie ausgehend von einem Verzeichnis Dateien finden. Dabei können verschiedene Filter gesetzt werden, die die gefundenen Dateien erfüllen müssen:

  • -type: Typ der Datei, z.B. Verzeichnis (d), normale Datei (regular file) f etc.
  • -name: Name der Datei, hier können glob-Muster, wie *,?, ranges ([..] mit Negation [^..] verwendet werden.
  • -iname: wie -name, aber case-insensitiv (d.h. insensitiv auf Groß- und Kleinschreibung)
  • -path (case-insensitive -ipath): analog -name, aber das glob-Muster bezieht sich auf den vollständige Pfad zur Datei. So kann man Pfade einschränken und den Verzeichnistrenner / verwenden.
  • -mtime Modifikationsdatum (-atime Zugriffsdatum) in 24h Einheiten
  • -mmin Modifikationsdatum in Minuten
  • -size Größe

Beispiel: Alle Verzeichnisse ausgehend vom Home-Verzeichnis, die im Namen "HTW" enthalten: find ~ -name "*HTW*" -type d

Für weitere Optionen, wie Suche nach Datum, Benutzer etc. siehe https://wiki.ubuntuusers.de/find/
Für eine ausführliche Dokumentation, siehe https://www.gnu.org/software/findutils/manual/html_mono/find.html#Full-Name-Patterns. Aber natürlich gibt es auch eine man-Page (man find) und https://tldr.ostera.io/find.

Etliche Beispiele finden Sie auch hier: https://alvinalexander.com/unix/edu/examples/find.shtml

Wiederholung: Beachten Sie, dass die Shell Wildcards -falls möglich- per Globbing direkt auflöst, bevor die Argumente zum Befehl (hier find) weitergereicht werden. Mit find ~/development -name *.py würde das *.py durch die im laufenden Arbeitsverzeichnis befindlichen Python-Dateien ersetzt werden, wenn hier Dateien mit Endung .py vorhanden sind. Daher ist unbedingt ein Quoting vozunehmen:find ~/development -iname "*.py"

Hinweise zu den Mengenangaben, wie z.B. Zeitangaben:

- und + vor der Mengenangabe bedeutet kleiner bzw. größer, z.B.:

Finde alle Dateien unter dem Download Ordner, die nicht älter als 24h sind:

find ~/Downloads/ -mtime -1

Beachte: Finde alle Dateien unter dem Download Ordner, die genau 24h alt sind. Das will man in der Regel nicht!

find ~/Downloads/ -mtime 1

Finde alle Dateien unter dem Download Ordner, die älter als 24h sind:

find ~/Downloads/ -mtime +1

Weitere Beispiele

Finde ausgehend vom Arbeitsverzeichnis alle Verzeichnisse mit Namen "Lehre":

find ~ -name "Lehre" -type d

Finde ausgehend vom Arbeitsverzeichnis alle Verzeichnisse mit Namen "lehre" (beliebige Groß-Kleinschreibung):

find ~ -iname "lehre" -type d

Finde alle regulären Dateien mit Endung ".ipynb" unter dem Home-Directory, die im Pfad ein Verzeichnis "julia" haben:

find ~ -path "*/julia/*.ipynb" -type f

Finde alle Dateien mit Endung ".tar.gz", die zwischen 200k und 5M groß sind:

find . -size +200k -size -5M -name '*.tar.gz'

Beachten Sie, dass unter Umständen das Glob-Muster in Anführungszeichen gesetzt werden muss (Quoting), damit die Shell es nicht vor dem Weiterleiten zu find auflöst.

Übung

Aufgabe
  • Finden Sie mit Hilfe von find alle python Dateien (Endung .py) ausgehend vom Home-Verzeichnis.

Aufgabe

Finden Sie alle Verzeichnisse mit "HTW" im Verzeichnisnamen ausgehend z.B. vom laufenden Arbeits-Verzeichnis. So soll z.B. "./.../myHTW-public/" gefunden werden.

Aufgabe

Welche von den folgenden Dateien werden bei

1.find . -name "*[0-9]*.ipynb"

2.find . -iname "[[:digit:]]*.ipynb"

gefunden? Annahme: Alle Dateien liegen unter dem laufenden Arbeitsverzeichnis (entweder direkt oder in Unterverzeichnissen).

  1. 30-Beispiel.ipynb
  2. a-30-Beispiel.ipynb.txt
  3. a-30.ipynb
  4. Beispiel.ipynb
  5. 2-a.IPYNB

Aufgabe

Finden Sie alle zip-Dateien (Endung .zip) mit einer Größe zwischen 200k und 1M.

Aufgabe

Finden Sie alle C++-Dateien (Annahme: erkennbar an der Endung .cpp), die in den letzten 5 Tagen (genauer 5 $\cdot$ 24h) modifiziert wurden (ausgehend vom Arbeitsverzeichnis).

Aufgabe

Lösche alle Dateien mit Endung .temp ausgehend vom Arbeitsverzeichnis (auch in allen Unterverzeichnissen!).

Hinweis:

  • Recherchieren Sie hierzu die Benutzung des Schalter -exec

locate

Hinweis: Neben find gibt es auch den Befehl locate zum Finden von Dateien. Dieser benutzt eine Datenbank, die ab und an aktualisiert wird. Daher ist locate schneller. Es kann aber passieren, dass neu geänderte Datei(namen) nicht gefunden werden. Die Datenbank wird mit Hilfe eines cron-Jobs (mehr zu cron später) in der Regel täglich aktualisiert. Sie kann auch mittels sudo updatedb manuell aktualisiert werden.

Mehr zu locate in der Manpage oder unter https://wiki.ubuntuusers.de/locate/

Reguläre Ausdrücke

Mit Hilfe Regulärer Ausdrücke (regular expressions, kurz Regex) können Zeichenketten (Texte) auf Muster durchsucht werden oder überprüft werden etc. Bei einer Suche kann man beispielsweise als Ergebnis die Bereiche (typischerweise Zeilen) erhalten, in denen das Muster gefunden wird.

Reguläre Ausdrücke gibt es für alle gängigen Programmiersprachen und auch für viele Textanwendungen (Editoren oder Textverarbeitungsprogramme) zur Suche. Dabei gibt es oft kleine Unterschiede bzgl. der Syntax der Ausdrücke. Ein weiteres Anwendungsbeispiel neben der Suche ist die Überprüfung von Usereingaben, z.B. ob in einem Webformularen eine gültige E-Mail Adresse eingegeben wurde.

Reguläre Ausdrücke vs. Dateinamen-Globbing

Beachten Sie, dass reguläre Ausdrücke und Dateinamen-Globbing zwei unterschiedliche Dinge sind.

Hinweis: Zu Glob gibt es auch eine Manpage: man glob

grep

Der Befehl grep dient zum Finden von Text-Mustern ausgedrückt durch reguläre Ausdrücke, z.B. in stdout oder Textdateien.

Arbeiten Sie folgende Beschreibung von RegEx (eventuell parallel mit der Regex-Übung, siehe unten) und grep durch: https://wiki.ubuntuusers.de/grep/

Hinweis: Es gibt auch eine Manpage: man regex

Übung

Arbeiten Sie die Übung "Reguäre Ausdrücke" (jupyter notebook regular-expression-exercise.ipynb) durch.

Beachten Sie, dass die gängige Regex-Syntax den extended regular expressions der Bash entspricht.

Übung

Aufgabe

In allen Dateien im laufenden Verzeichnis mit Endung .txt, die mit a anfangen, soll folgendes Textmuster gefunden: ein a gefolgt von beliebig vielen Zeichen und dann die Zeichenfolge txt, z.B. soll folgende Zeile ausgegeben werden:

Die Dokumente werden gelöscht, aber txt-Dateien sind nicht betroffen.
Aufgabe

Welche python-Dateien (alle unter einem bestimmten Verzeichnis inkl. alle Unterverzeichnisse) haben im Code eine Zeichenfolge TODO? Gehen Sie davon aus, dass die Dateienamen keine Leerzeichen enthalten. Im Ergebnis soll die Dateien (inkl. Pfad) und die Zeile, auf der das Muster "TODO" zutreffen, angezeigt werden.

Geben Sie zwei Lösungen an:

  1. Nutzen des -execSchalters von find für grep.
  2. Pipen des stdout-outputs des find-Kommandos und verwenden von xargs und grep. R
In [7]:
# Nehmen Sie an, dass das zu durchsuchende Verzeichnis (inkl. Unterverzeichnis)
# in folgender Variablen gespeichert ist. Sie sollten zum Ausprobieren den Pfad ändern.
SEARCHPATH=~/HTW-nextcloud/Lehre/dataScience/reinforcement-learning

# Variablen werden weiter unten erklärt.

Aufgabe

Mit Hilfe des Kommandos history kann man die zuletzt verwendten Befehle erhalten. Welche zuletzt verwendeten Befehle haben Sie benutzt, die find und maxdepth enthalten?

Randmerkung: Diese Information wird in der Datei ~/.bash_history abgespeichert. Nutzen Sie aber nicht diese Datei direkt, sondern verwenden Sie den Befehl history.

Aufgabe

Wie kann man nur die Dateien im Arbeitsverzeichnis mit Endung .ipynb anzeigen (unter der Benutzung von ls), deren Dateiname mindestens 2 Zahlen in Folge enthält?

find direkt mit regulären Ausdrücken

Mit Hilfe des Schalters -regex kann bei find anstatt eines Glob-Musters ein regulärer Ausdruck verwendet werden. Welcher Art von regulären Ausdrücke angewendet werden soll, kann mittels -regextype eingestellt werden.

Beispiel:

In [10]:
find .. -maxdepth 1 -regextype "posix-extended" -regex '.*[0-9]{1,10}.*\.ipynb'
echo ------------
# ist äquivalent zu 
ls ../*.ipynb | grep -E '[0-9]{1,10}'
../bash_1.ipynb
../bash_4.ipynb
../bash_3.ipynb
../bash_2.ipynb
../bash_5.ipynb
------------
../bash_1.ipynb
../bash_2.ipynb
../bash_3.ipynb
../bash_4.ipynb
../bash_5.ipynb

Variablen

In Bash können Werte in Variablen gespeichert werden.

Um einen Wert einer Variablen zuzuordnen, wird der Zuweisungsoperator = verwendet.

In [11]:
my_var=5

Beachten Sie dabei, dass hier keine Leerzeichen beim = stehen dürfen. Warum könnte das so (restriktiv) sein? Probieren Sie es aus und erklären Sie die Fehlermeldungen.

Beachten Sie dies immer, da dies zu Beginn verwirrend ist und leicht zu Fehlern führen kann.

In der Shell-Terminologie ist eine Variable auch ein Shell Parameter. Ein Parameter ist eine Entität, die einen Wert enthalten kann. Eine Variable ist ein Parameter mit einem Namen (hier my_var).

Der Inhalt einer Variablen kann mit Parameter Expansion ausgelesen werden. Parameter Expansion startet mit einem $, z.B.:

In [12]:
echo $my_var
5

Manchmal muss man geschweifte Klammern setzen, um den Variablennamen vom Folgenden zu trennen, wie hier

In [13]:
echo ${my_var}er
5er

Randbemerkung: Der grundlegende Type einer Variable ist String. Mit declare können aber Attribute gesetzt werden, wie z.B. das integer attribute.

Da im Prinzip alle Variablen Strings sind, hat die bash(-Programmiersprache) nicht wirklich Typen. "Schreibe Programme so, dass sie Textströme verarbeiten, denn das ist eine universelle Schnittstelle." (vgl. Unix-Philosophie).

In diesem Sinne ist die bash sehr einfach und dient oft nur einfachen administrativen Aufgaben (nahe am Betriebsystem bzw. Befehlsinterpreter).

Für komplexere adminstrative Aufgaben wird daher oft die Programmiersprache Python eingesetzt, die erheblich mächtiger ist und die typisiert ist.

Quoting

Längere Strings mit Leerzeichen können durch die Anführungszeichen " oder ' geschützt werden (Quoting).

In [14]:
greetings="Hallo Welt!"

Beachte den Unterschied:

In [15]:
my_var="-$greetings- ist ein Gruß."
echo $my_var
-Hallo Welt!- ist ein Gruß.
In [16]:
my_var='-$greetings- ist ein Gruß.'
echo $my_var
-$greetings- ist ein Gruß.

Bei den einfachen Anführungszeichen werden die Inhalte direkt angezeigt, ohne dass z.B. Variablen expandiert werden. Erinnerung: bei doppelten Anführungszeichen wird das Globbing von der Shell nicht aufgelöst:

In [17]:
#`-e` enable interpretation of backslash escapes
echo -e "Quoting: *.txt vs. \nExpansion:" *.txt
Quoting: *.txt vs. 
Expansion: countries_1.txt countries_2.txt countries_3.txt countries_4.txt countries_second_hard_link.txt countries_soft_link.txt countries.txt f2.txt f.txt inhalt_des_verzeichnisses.txt ls-out.txt mylog.txt rechnernamen.txt stderr.txt text_with_urls.txt t.txt

Beachte: Einige Zeichen, wie "$" oder "&", müssen escaped werden:

In [18]:
echo Du schuldest mir $5! # Erklären Sie die Ausgaben!
echo "Du schuldest mir $5!"

echo "Du schuldest mir \$5!"
echo 'Du schuldest mir $5!' # escaping nicht nötig bei "single quotes"
Du schuldest mir !
Du schuldest mir !
Du schuldest mir $5!
Du schuldest mir $5!

Substrings

In [19]:
Length=5
echo ${greetings:0:Length}
Hallo
In [20]:
echo ${greetings: -5} # Das Leerzeichen ist wichtig!
Welt!
In [21]:
# sonst geht es nicht:
echo ${greetings:-5}
Hallo Welt!

String Länge

In [22]:
echo ${#greetings}
11

Ersetzungen und Beseitigungen in Variablen

Beseitigungen mit Mustern am Anfang und Ende

Beseitigung am Anfang von Dateien:

  • ${var#Muster}: Beseitigt kürzesten Teil des Musters
  • ${var##Muster}: Beseitigt längsten Teil des Musters

Beseitigung am Ende von Dateien:

  • ${var%Muster}: Beseitigt kürzesten Teil des Musters
  • ${var%%Muster}: Beseitigt längsten Teil des Musters

Ersetzungen am Anfang:

  • ${var/#from/to}: Ersetzt kürzesten Teil des Musters
  • ${var/##from/to}: Ersetzt längsten Teil des Musters

Ersetzungen am Ende:

  • ${var/%from/to}: Ersetzt kürzesten Teil des Musters
  • ${var/%%from/to}: Ersetzt längsten Teil des Musters

Ersetzungen allgemein:

  • ${var/from/to}: Ersetze ersten Treffer
  • ${var//from/to}: Ersetze alle

Beispiele:

In [23]:
echo $greetings

# Ersetze "Hallo" mit "Grüße an die" in der Variable greetings
echo ${greetings/Hallo/Grüße an die}
Hallo Welt!
Grüße an die Welt!
In [24]:
var="http://christianherta.de/lehre/informatik/von_neumann_architektur.html"
echo "${var#*/}"
echo "${var##*/}"
/christianherta.de/lehre/informatik/von_neumann_architektur.html
von_neumann_architektur.html
In [25]:
var=/path/to/a/image.old.png
echo "${var%png}"jpg
echo "${var%.*}".jpg
echo "${var%%.*}".jpg
/path/to/a/image.old.jpg
/path/to/a/image.old.jpg
/path/to/a/image.jpg

Indirekte Expansion

In [26]:
echo $greetings
Hallo Welt!
In [27]:
andere_variable="greetings" # Speichere den Variablennamen "greetings" in einer Varaiblen  
echo ${andere_variable} 
echo ${!andere_variable}
greetings
Hallo Welt!

Default Values

In [28]:
echo ${foo:-"Wenn Variable 'foo' nicht gesetzt, wird dies verwendet."}
Wenn Variable 'foo' nicht gesetzt, wird dies verwendet.
Übung

Beantworten Sie folgende Fragen:

  • Wie kann man einfach aus der Variable Var="Ich bin die Königin der Kommandozeile." eine neue Variable Var1 erstellen, wobei das bin die Königin der durch beherrsche die ersetzt wurde.
  • Wie kann man aus der Variablen Var die Zeichen 19 bis zum Ende ausschneiden?
  • Wie kann man aus der Variablen Var die Zeichen 19 bis vorletzten Zeichen ausschneiden, d.h. nicht en abschließenden Punkt?
In [29]:
Var="Ich bin die Königin der Kommandozeile."

Substitutions

Command Substitution

$(kommando) Das Kommando innerhalb der Klammern wird in einer Subshell (siehe unten) ausgeführt und stdout des Kommandos als Rückgabewert erhalten. Das wird auch als command substitution bezeichnet.

Beispiel:

In [32]:
ls -la $(which ping)
# alternativ zu  
#which ping | xargs ls -la
-rwsr-xr-x 1 root root 64424 Jun 28  2019 /bin/ping
In [34]:
# alternative Syntax für Command Substitution per Backticks
ls -la `which ping`
-rwsr-xr-x 1 root root 64424 Jun 28  2019 /bin/ping

Subshells

Subshells werden als Kopien (der Umgebung) von der ursprünglichen Shell gestartet (als Subprozess) - mehr zu Subshells (und Prozessen) später.

Hinweis: Subshells werden auch beim Pipen erzeugt, was zu subtilen Fehlern führen kann (siehe unten).

Expansion mit dem $-Zeichen und Subshells

Mit runden Klammern werden Subshells erzeugt.

  • $(...) Das Kommando innerhalb der Klammern wird in einer Subshell ausgeführt und stdout des Kommandos als Rückgabewert erhalten. Das wird auch als command substitution bezeichnet.
  • (...) Das Kommando innerhalb der Klammern wird in einer Subshell ausgeführt (ohne Rückgabewert).
In [35]:
echo "The current date is $(date)"
# alternative mit backticks "`" 
echo "The current date is `date`"
The current date is Di 16. Nov 18:30:05 CET 2021
The current date is Di 16. Nov 18:30:05 CET 2021
In [36]:
ls -l $(which who)
-rwxr-xr-x 1 root root 51416 Jan 18  2018 /usr/bin/who

Kommandos in Gruppe

Bei Kommando innerhalb geschweifter Klammern:

  • {...} Führt die Kommandos in den geschweiften Klammern als Gruppe aus.

Dabei muss immer ein Leerzeichen zwischen den geschweiften Klammern und den Befehlen darin stehen. Außerdem müssen alle Befehle mit einem ; abgeschlossen werden.

So lassen sich bespielsweise alle Ausgaben einer Kette von Kommandos gemeinsam in eine Datei umleiten:

{ echo "I found all these PNGs:"; find . -iname "*.png"; echo "Within this bunch of files:"; ls; } > PNGs.txt
Beispiel aus All-about curly braces in Bash.

In [37]:
echo direkt
a=9 # setze die Variable in der Shell
echo $(echo $a) # in der Subshell ist die Variable verfügbar
echo PID:$BASHPID

echo -------------------------

echo Subshell
(b=10, echo PID:$BASHPID) # setze die Variable in einer Subshell
# in der aufrufenden Shell ist die Variable nicht gesetzt!
echo $b

echo -------------------------
echo Gruppe
{ c=119; echo PID:$BASHPID; } 
# in der aufrufenden Shell ist die Variable gesetzt!
echo $c
direkt
9
PID:18697
-------------------------
Subshell
PID:18798

-------------------------
Gruppe
PID:18697
119
In [38]:
# das gilt natürlich auch für Änderungen von Variablen 
a=1; (a=2; echo "inside: a=$a"); echo "outside: a=$a"
inside: a=2
outside: a=1
Aufgabe

Wie kann man (einfach) den Inhalt einer Datei in eine Variable einlesen?

Aufgabe

Wie kann man etliche Befehle ausführen und danach wieder im Ursprungsverzechnis sein? z.B.

cd ~ ; cat *.txt ; ls -l ; cd my_dir1; cat *.txt

Aufgabe

Was ist der Unterschied zwischen Kommandos, die in runden ( .. ) und geschweiften Klammern { .. } ausgeführt werden?

Process Substitution

<( kommando ) erzeugt eine anonyme named pipe und verbindet stdout des Kommandos mit der named pipe. An der Stelle wird der Dateiname der named pipe zurückgegeben. Das ist sinnvoll für andere Kommandos denen typischerweise ein Dateinamen übergeben wird.

In [40]:
# cat bekommt einen Dateinamen als Input
# Dies demonstriert das Prinzip der process substitution
cat <(echo das landet in der Datei)
das landet in der Datei

Das ist effektiv das Gleiche wie:

In [41]:
# hier liest cat von stdin
echo das landet in der Datei | cat
das landet in der Datei
In [44]:
# hier wird der Dateiname (fd - file descriptor) ausgegeben
# dies ist in der Regel uninteressant - hier nur zur Demonstration
echo <( echo Hallo )
/dev/fd/63

Aber es sind bei Process Substitution auch mehrere Kommandos möglich:

In [45]:
cat <(echo bar; echo foo) 
# mittels ";" können mehrere Befehle in eine Zeile geschrieben werden
# Diese werden dann hintereinander ausgeführt.
bar
foo

Anwendungsbeispiel für Process Substitution

Wir wollen die von wc zurückgelieferten Informationen in Variablen speichern:

In [46]:
echo "Hallo Welt
Hello World
Hola mundo" > greetings

# Ein sinnvolles Beispiel
# greetings ist eine Textdatei!
# und wc zählt die Zeilen, Wörten und Zeichen
read lines words chars _ < <(wc greetings)
# lines words und chars sind Variablen (später mehr dazu)
# um den Inhalt von Variablen zu bekommen benötigt man das "$" 
echo $lines
echo $words
echo $chars
3
6
34

Erklärung:

In [47]:
# zur Demonstration von wordcount-programm "wc"
# mehr zu wc siehe z.B. "man wc"
wc greetings
 3  6 34 greetings

Erklärung von read lines words chars _ < <(wc greetings):

  • read - Read a line from the standard input and split it into fields - (siehe help read)
  • <(wc greetings) erzeugt mittels Process substitution eine named pipe temporäre Datei
  • das erste < leitet den Inhalt der named pipe-temporären Datei zu read
In [48]:
type read
read is a shell builtin

Beachte, dass folgender Code nicht funktioniert, da die Pipe eine Subshell erzeugt und die Variablen in der aufrufenden Shell (ohne Tricks) nicht mehr verfügbar sind, siehe z.B. https://stackoverflow.com/questions/46946888/bash-pipe-creates-a-subshell.

In [49]:
words= ; lines= ; chars= # delete the content of the variables
wc greetings | read lines words chars
echo $lines $words $chars # die Variablen sind nicht gesetzt!

Aufgabe

Erklären Sie folgendes:

mkdir foo bar
touch {foo,bar}/{a..h}
touch foo/x bar/y
diff <(ls foo) <(ls bar)

Recherchieren Sie hierzu auch kurz das diff-Kommando (wird später nochmal behandelt).

Here-Strings und Here-Dokumente

Beispiel für ein here document (<<).

$wc << EOF
Das ist ein
Dokument über mehrere Zeilen
EOF

Die Zeichenkette (hier EOF), die das Ende des mehrzeiligen Dokumentes angibt, kann beliebig gewählt werden.

In [52]:
# bc ist ein eigentlich ein interaktiver Calculator
# mehr siehe `man bc`
bc << End
a=3
b=5
a*b
End
15
In [53]:
# Demonstration des Dokumentes, das bc in obigem Beispiel erhält:
cat << End
a=3
b=5
a*b
End
a=3
b=5
a*b

Beipiel für ein here string (<<<)

In [54]:
bc <<< 4*5
20
In [55]:
echo "12+5" | bc
17
In [56]:
cat <<< 4*5
4*5

Beachte: here documents und here strings werden an Stelle einer Datei eingesetzt.

here documents und here strings werden in bash mittels temporärer Dateien realisiert.

Mehr dazu siehe z.B.: https://askubuntu.com/questions/678915/whats-the-difference-between-and-in-bash

Eine typische Anwendung von here strings (und here documents) ist auf einem entfernten Rechner (per ssh oder sftp) mehrere Kommandos auszuführen, die in einem here string gesetzt werden (genaueres später).

Weitere Anwendung: Einen anderen Interpreter, z.B. Python, aus der bash mit Befehlen aufrufen:

In [57]:
# Python Interpreter aufrufen mit "Hallo Welt"-Programm 
python <<< "print ('Hallo Welt')"

# ist einfacher als die Alternative mit Process Substitution und stdout-Umleitung
python < <(echo "print('Hallo Welt')")
Hallo Welt
Hallo Welt
In [58]:
# mit einem here-Dokument
python << BOF
print ('Hallo Welt')
print ('sagt das mehrzeilige Python3 Programm.')
BOF
Hallo Welt
sagt das mehrzeilige Python3 Programm.
Übung
Aufgabe

Mit Hilfe des Programms du (disc usage) können Sie sich anzeigen lassen, wieviel Speicher Verzeichnisse (inkl. Unterverzeichnisse) belegen, siehe man du.

Wie kann man alle Verzeichnisse direkt unter dem eigenen Heimverzeichnis erhalten (inkl. Speicherverbrauch), die mehr als ein Gigabyte verbrauchen?

Hinweis: du mit Schalter -h und --max-depth in Kombination mit grep.

Aufgabe

Kopieren Sie alle regulären Dateien im Downloadordner (~/Downloads/), die in den letzen 60 Minuten modifiziert worden sind, in den Order ~/data/gene-expression/.

Aufgabe

Kopieren Sie alle pdf- und png-Dateien (Endungen pdf bzw. png case-insensitive) des laufenden Arbeitsverzeichnis, die jünger als der 8.März sind, in das Verzeichnis (./rechungen).

Aufgabe

Gegeben ist ein beliebiger relativer (oder absoluter) Pfad zu einer Datei, z.B. ../work/countries.txt. Bestimmen Sie hieraus den Namen und den absoluten Pfad der Datei und speichern Sie diese in zwei Variablen. Der absolute Pfad sollte keinen . oder .. enthalten.

Hinweis: Benutzen Sie (unter anderem) die Posix-konformen Kommandos:

  • basename
  • dirname
In [ ]:
whatis basename
whatis dirname
In [ ]:
# Ihre Lösung sollte mit einem beliebigen relativen 
# oder auch absoluten folgendem Pfad zurecht kommen, wie z.B.
myfile=../work/countries.txt