fonctions lambda dans bash

Existe-t-il un moyen d'implémenter/utiliser des fonctions lambda dans bash? Je pense à quelque chose comme:

$ someCommand | xargs -L1 (lambda function)
24
demandé sur John Kugelman 2009-01-15 22:30:37

5 réponses

Je ne connais pas de moyen de le faire, mais vous pourrez peut-être accomplir ce que vous essayez de faire en utilisant:

somecommand | while read -r; do echo "Something with $REPLY"; done

Ce sera également plus rapide, car vous ne créerez pas de nouveau processus pour chaque ligne de texte.

[modifier 2009-07-09] J'ai fait deux changements:

  1. a incorporé la suggestion de litb d'utiliser -r pour désactiver le traitement des barres obliques inverses - cela signifie que les barres obliques inverses dans l'entrée seront transmises inchangées.
  2. au lieu de fournir un nom de la variable (comme X) en tant que paramètre à read, nous laissons read affecter à sa variable par défaut, REPLY. Cela a l'effet secondaire agréable de préserver les espaces avant et arrière, qui sont dépouillés autrement (même si les espaces internes sont préservés).

D'après mes observations, ensemble ces changements préservent tout sauf les caractères NUL (ASCII 0) littéraux sur chaque ligne d'entrée.

[MODIFIER 26/7/2016]

Selon commentateur Evi1M4chine, définir $IFS sur la chaîne vide avant d'exécuter read X (par exemple, avec la commande IFS='' read X) devrait également préserver les espaces au début et à la fin lors du stockage du résultat dans $X, ce qui signifie que vous n'êtes pas obligé d'utiliser $REPLY.

21
répondu j_random_hacker 2016-07-26 09:34:31

Si vous voulez de vraies fonctions, et pas seulement des pipes ou des boucles while (par exemple si vous voulez les passer, comme s'il s'agissait de données), Je ne ferais tout simplement pas de lambdas, et définirais des fonctions fictives avec un nom fictif récurrent, à utiliser tout de suite, et jeter après. Comme ça:

# An example map function, to use in the example below.
map() { local f="$1"; shift; for i in "$@"; do "$f" "$i"; done; }

# Lambda function [λ], passed to the map function.
λ(){ echo "Lambda sees $1"; }; map λ *

Comme dans les langages fonctionnels appropriés, il n'est pas nécessaire de passer des paramètres, car vous pouvez les envelopper dans une fermeture:

# Let’s say you have a function with three parameters
# that you want to use as a lambda:
# (As in: Partial function application.)
trio(){ echo "$1 Lambda sees $3 $2"; }

# And there are two values that you want to use to parametrize a
# function that shall be your lambda.
pre="<<<"
post=">>>"

# Then you’d just wrap them in a closure, and be done with it:
λ(){ trio "$pre" "$post" "$@"; }; map λ *

Je dirais que c'est encore plus court que toutes les autres solutions présentées ici.

8
répondu Evi1M4chine 2013-12-19 08:46:15

Et ça?

somecommand | xargs -d"\n" -I{} echo "the argument is: {}"

(suppose que chaque argument est une ligne, sinon modifiez le délimiteur)

3
répondu 2009-03-01 16:01:11

Si vous ne voulez que xargs (option parallèle -P N par exemple), et seulement bash comme code de fonction, alors bash -c peut être utilisé comme paramètre pour xargs.

seq 1 10 | tr '\n' '\0' | xargs -0 -n 1 bash -c 'echo any bash code $0'

Les options Tr et -0 sont utilisées ici pour désactiver les substitutions de paramètres xargs.

1
répondu dobrokot 2011-10-24 14:14:37

Oui. On peut passer autour d'une variable de chaîne représentant un appel de commande, puis exécuter la commande avec eval.

Exemple:

command='echo howdy'
eval "$command"
0
répondu mcandre 2018-02-27 20:02:33