Échapper les citations dans l'alias zsh

12

À la suite de cette question sur la suppression des nouvelles lignes du texte, je veux transformer cela en un alias zsh comme suit:

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

J'ai essayé d'échapper les guillemets à l'intérieur du script awk, mais j'obtiens cette erreur:

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

(Le fichier est appelé bspsrobustness)

Existe-t-il un moyen de faire ce que je veux? Je suppose que je pourrais transformer cela en un script awk plutôt qu'en un alias zsh, est-ce ma meilleure option?

Seamus
la source
Soit dit en passant, cela s'applique à tous les shells (style Bourne, pas csh).
Gilles 'SO- arrête d'être méchant'

Réponses:

9

Vous pouvez utiliser une fonction zsh au lieu d'un alias. Pas de cerceaux pour sauter.

striplines() {
    awk '... awk body "with quotes" ...' "$@"
}
glenn jackman
la source
Et puis comment pourrais-je l'appeler striplines filename:?
Seamus
pourriez-vous expliquer ce que le "$@"fait?
Seamus
@Seamus, oui, vous l'appelleriez exactement comme ça. La "$@"syntaxe envoie les arguments striplines à awk sans être dérangé - nécessaire si, disons, l'un de vos noms de fichiers contient des espaces: striplines "file 1" "file 2"enverrait deux noms de fichiers à awk.
glenn jackman le
5

Pour avoir une idée de ce qui se passe, lancez

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

Étant donné que les $caractères sont entre guillemets (lorsqu'ils sont développés après le développement de l'alias), ils sont interprétés par le shell. Pour obtenir le bon devis, il est plus facile de mettre la définition d'alias entière entre guillemets simples. Ce qui se trouve à l'intérieur des guillemets simples est ce qui sera développé lorsque l'alias est utilisé. Maintenant que l'argument de awkest entouré de guillemets, il est clair que vous avez besoin de barres obliques inverses avant \"$.

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

Un idiome utile pour mettre entre guillemets simples une chaîne entre guillemets simples est que '\''c'est à peu près un moyen de mettre une citation simple littérale dans une chaîne entre guillemets simples. Techniquement, il existe une juxtaposition d'une chaîne entre guillemets simples, d'une barre oblique inverse 'et d'une autre chaîne entre guillemets simples. La chaîne vide juxtaposée ''à la fin peut être supprimée.

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

Après cette longue explication, une recommandation: quand c'est trop compliqué pour un alias, utilisez une fonction .

Gilles 'SO- arrête d'être méchant'
la source