Escape-Anführungszeichen in zsh-Alias

12

Nach dieser Frage zum Entfernen von Zeilenumbrüchen aus dem Text möchte ich dies wie folgt in einen zsh-Alias ​​umwandeln:

alias striplines=' awk " /^$/ {print \"\n\"; } /./ {printf( \" %s \",$0);}"'

Ich habe versucht, die Anführungszeichen im awk-Skript zu umgehen, erhalte jedoch den folgenden Fehler:

awk: (FILENAME=bspsrobustness FNR=1) fatal: division by zero attempted

(Die Datei heißt bspsrobustness)

Gibt es eine Möglichkeit zu tun, was ich will? Ich nehme an, ich könnte dies eher in ein awk-Skript als in einen zsh-Alias ​​verwandeln. Ist das meine beste Option?

Seamus
quelle
Dies gilt übrigens für alle (Bourne-artigen, nicht csh) Shells.
Gilles 'SO - hör auf böse zu sein'

Antworten:

9

Sie können eine zsh-Funktion anstelle eines Alias ​​verwenden. Keine zitierenden Reifen zum Durchspringen.

striplines() {
    awk '... awk body "with quotes" ...' "$@"
}
Glenn Jackman
quelle
Und wie würde ich es dann nennen : striplines filename?
Seamus
Könntest du erklären, was der "$@"macht?
Seamus
@Seamus, ja du würdest es genau so nennen. Die "$@"Syntax sendet die Striplines-Argumente ungestört an awk - erforderlich, wenn beispielsweise einer Ihrer Dateinamen Leerzeichen enthält: striplines "file 1" "file 2"würde zwei Dateinamen an awk senden.
Glenn Jackman
5

Um eine Vorstellung davon zu bekommen, was los ist, laufen Sie

% alias striplines='print -lr awk " /^$/ {print \"\n\"; } /./ {printf( \" %s \",$0);}"'
% striplines
awk
 /^$/ {print "\n"; } /./ {printf( " %s ",zsh);}

Da die $Zeichen in doppelten Anführungszeichen stehen (wenn sie nach dem Erweitern des Alias ​​erweitert werden), werden sie von der Shell interpretiert. Um das Angebot in Anführungszeichen zu setzen, ist es einfacher, die gesamte Aliasdefinition in einfache Anführungszeichen zu setzen. In den einfachen Anführungszeichen wird erweitert, wenn der Alias ​​verwendet wird. Jetzt, da das Argument von awkin doppelte Anführungszeichen gesetzt ist, ist klar, dass Sie vorher Backslashes benötigen \"$.

alias striplines='print -lr awk " /^\$/ {print \"\n\"; } /./ {printf( \" %s \",\$0);}"'

Eine nützliche Redewendung, um eine Zeichenfolge in '\''einfachen Anführungszeichen zu setzen, ist, dass es so ziemlich eine Möglichkeit ist, ein wörtliches einfaches Anführungszeichen in eine Zeichenfolge in einfachen Anführungszeichen zu setzen. Technisch gesehen gibt es eine Gegenüberstellung einer Zeichenfolge in einfachen Anführungszeichen, einer Zeichenfolge mit umgekehrten Schrägstrichen 'und einer anderen Zeichenfolge in einfachen Anführungszeichen. Die nebeneinander angeordnete leere Zeichenfolge ''am Ende kann entfernt werden.

alias striplines='print -lr awk '\'' /^$/ {print "\n"; } /./ {printf( " %s ",$0);}'\'

Nach dieser langen Erklärung eine Empfehlung: Wenn es für einen Alias ​​zu kompliziert ist, verwenden Sie eine Funktion .

Gilles 'SO - hör auf böse zu sein'
quelle