Wie schreibe ich einen Bash-Alias, der! $ Durch das letzte Wort des vorherigen Befehls ersetzt?

346
Greg Bacon

Ich habe ein Skript namens cpodin, das mehrere Build-Artefakte in ein anderes Verzeichnis kopiert. Danach bearbeite ich SHA1SUMdas Zielverzeichnis.

Zum Beispiel:

cpodin /foo/bar/baz vim !$/SHA1SUM 

Wie mache ich aus dem letzten Befehl einen Aliasnamen fixsha, der kein Argument akzeptiert SHA1SUMund das Verzeichnis bearbeitet, das durch das letzte Argument des vorherigen Befehls benannt wurde? Ein Alias ​​von

alias fixsha='vim !$/SHA1SUM' 

führt zu Versuchen, !$/SHA1SUMstatt zu bearbeiten /foo/bar/baz/SHA1SUM.

1

1 Antwort auf die Frage

2
Greg Bacon

Bash führt nach der Aliaserweiterung keine Verlaufserweiterung durch, daher müssen Sie dies explizit verwenden history, wie in Bash History Builtins dokumentiert und im Folgenden beschrieben.

history -ps args

  • -p
    Führen Sie die Ersetzung der Historie in den Argumenten durch und zeigen Sie das Ergebnis in der Standardausgabe an, ohne die Ergebnisse in der Historienliste zu speichern.
  • -s
    Die Argumente werden als einzelner Eintrag am Ende der Verlaufsliste hinzugefügt.

Ein Alias ​​von alias fixsha='vim $(history -p !$)/SHA1SUM'funktioniert meistens, aber nicht wie beabsichtigt, wenn er !$auf einen Pfad erweitert wird, der Leerzeichen enthält. Durch das Hinzufügen von Anführungszeichen um das Pfadargument werden alle Leerzeichen und Leerzeichen geschützt und die Ergebnisse werden vim "/foo/bar\ baz/SHA1SUM"eher als gewünscht vim /foo/bar\ baz/SHA1SUModer gleichwertig dargestellt vim "/foo/bar baz/SHA1SUM".

Neben der expliziten Historienerweiterung evalist es daher auch notwendig, eine Notierungsebene aufzuheben.

alias fixsha='eval vim "$(history -p !$)/SHA1SUM"' 

Hinweis: Sie werden überrascht sein zu erfahren, dass die Anführungszeichen in der obigen Aliasdefinition nicht erforderlich sind. Dies liegt daran, dass kein Leerzeichen zwischen dem erweiterten Wert von !$und /SHA1SUMder Wortteilung von Bash ist. Ich mag es jedoch, dass sie da sind, um die Absicht zu betonen, dass sie sich zu einem einzigen Argument ausdehnt.