Under Construction

Zugriff auf Teile eines Kommandos der History

In vielen Fällen benötigt man nicht ein komplettes Kommando aus der History, sondern nur einen Teil des Kommandos, z.B. ein längeres Argument. Die Shell teilt eine Eingabe generell in Worte auf. Dabei ist das erste Wort das auszuführende Kommando und alle weiteren Worte sind die sogenannten Argumente für das Kommando. Worte sind dabei durch Leerzeichen voneinander getrennt. Über den History Mechanismus der bash kann man auf einzelne Worte bzw. Argumente von zurückliegenden Kommandos zugreifen. Dazu wird dem im vorigen Unterkapitel besprochenen Ereignis Bezeichner ein Doppelpunkt „:“ am Ende hinzugefügt, gefolgt von der Angabe der Nummer des gewünschten Wortes. Worte werden beginnend mit Null durchnummeriert. D.h. Wort 0 ist das Kommando selbst und das Wort 1 ist das erste Argument des Kommandos.

Wir starten mit der folgenden History:

[user01@aixe01 ~]$ history
    1  ls -l /usr
    2  vi sample.txt
    3  ls -l sample.txt
    4  cat sample.txt
    5  cp sample.txt working_copy_of_sample.txt
    6  cat sample.txt
    7  cat start.ksh
    8  cat stop.ksh
    9  history
[user01@aixe01 ~]$

Es soll die Datei working_copy_of_sample.txt mit vi editiert werden. Wir können natürlich das komplette Kommando eintippen:

[user01@aixe01 ~]$ vi working_copy_of_sample.txt

Das sind, inklusive Newline am Ende, 29 Zeichen!

Kürzer geht es über History Erweiterungen (Expansion). Die gewünschte Datei kommt im Kommando mit der Nummer 5 („cp sample.txt working_copy_of_sample.txt“) als zweites Argument (Wort mit der Nummer 2) vor. D.h. der History Mechanismus der bash würde „!5“ durch das komplette Kommando ersetzen (und ausführen). Fügt man jedoch, wie oben beschrieben, einen Doppelpunkt „:“ und die Nummer des Wortes (hier 2) hinzu, ergibt sich „!5:2“. Dies wird vom History Mechanismus der bash durch „working_copy_of_sample.txt“ ersetzt. D.h. anstelle die 29 Zeichen für „vi working_copy_of_sample.txt“ anzugeben, kann man auch kürzer „vi !5:2“ schreiben:

[user01@aixe01 ~]$ vi !5:2
vi working_copy_of_sample.txt

Das sind nur 8 Zeichen (inclusive Newline)!

Da das Kommando mit der Nummer 5 das letzte Kommando war, das mit „cp“ beginnt, könnte man natürlich auch „!cp:2“ verwenden. Das ist zwar ein Zeichen mehr, hat aber den Vorteil das man die Nummer des Kommandos nicht erinnern muss.

Alternativ kann man auch nach dem letzten Kommando suchen, das die Zeichenkette „working“ oder „work“ (oder auch nur „w“) enthält und dann auf das zweite Argument zugreifen:

[user01@aixe01 ~]$ vi !?work?:2
vi working_copy_of_sample.txt

Oder noch kürzer:

[user01@aixe01 ~]$ vi !?w?:2
vi working_copy_of_sample.txt

In all diesen Fällen muss man aber die Nummer für das richtige Argument angeben (hier jeweils die “2”). Anstelle der Nummer kann man nach dem Doppelpunkt aber auch das Prozentzeichen „%“ angeben, aber nur wenn im Ereignis Bezeichner Fragezeichen „?“ verwendet wurden. Das Prozentzeichen bezieht sich dann auf dasjenige Argument, in dem die angegebenen Zeichenkette gefunden wurde. Es spielt dann keine Rolle, ob dies das erste oder zweite Wort war, oder an irgendeiner anderen Position stand:

[user01@aixe01 ~]$ vi !?w?:%
vi working_copy_of_sample.txt

Man muss also dann nur noch wissen, das das benötigte Wort zuletzt als Argument bei irgendeinem Kommando vorkam und kann sich dann auf dieses Wort beziehen!

Neben der Angabe der Nummer des Wortes und dem Prozentzeichen für das Wort das auf den Suchstring gepasst hat, gibt es noch Abkürzungen für das erste und das letzte Wort (Argument):

    • ^   Das erste Wort (Argument), dies ist identisch zur Verwendung von „1“.
    • $   Das letzte Wort (Argument).

Bisher haben wir uns immer auf genau ein Wort bezogen. Man kann aber auch Bereiche von Worten angeben. Hat man Beispielsweise kürzlich das folgende echo Kommando verwendet:

[user01@aixe01 ~]$ echo A B C D E F
A B C D E F
[user01@aixe01 ~]$

Dann kann man sich mit der Bereichsangabe „2-4“ auf die Worte zwei bis vier beziehen:

[user01@aixe01 ~]$ echo !echo:2-4
echo B C D
B C D
[user01@aixe01 ~]$

Benötigt man alle Argumente (alle Worte nach dem Kommando), dann gibt es hierfür die naheliegende Abkürzung „*“:

[user01@aixe01 ~]$ banner !echo:*
banner A B C D E F
   #
  # #
#   #
#     #
#######
#     #
#     #

######
#     #
#     #
######
#     #
#     #
######

#####
#     #
#
#
#
#     #
#####

######
#     #
#     #
#     #
#     #
#     #
######

#######
#
#
#####
#
#
#######

#######
#
#
#####
#
#
#

[user01@aixe01 ~]$

Nachfolgend die vollständige Liste der möglichen Wort Bezeichner:

    • 0   Das nullte Wort, d.h. der Kommando-Name.
    • n   Das n-te Wort.
    • ^   Das erste Argument, dies ist Wort 1.
    • $   Das letzte Argument
    • % Das Wort, welches auf den Suchstring „?string?“ gepasst hat.
    • n-m   Der Bereich der Worte n bis m (einschließlich)
    • -m   Abkürzung für 0-m.
    • *   Alle Argumente, d.h. alle Worte außer dem Wort 0. Abkürzung für 1-$
    • n*   Abkürzung für n-$
    • n-   Alle Worte ab n, außer dem letzten Wort.