web-dev-qa-db-fra.com

Quel est l'équivalent de xargs dans PowerShell?

La commande définie par POSIX xargs prend tous les éléments qu'elle reçoit de l'entrée standard et les transmet comme arguments de ligne de commande à la commande reçue sur sa propre ligne de commande. Par exemple: grep -rn "String" | xargs rm.

Quel est l'équivalent dans PowerShell?

Les questions suivantes demandent toutes ceci:

mais il n'y a pas de bonne réponse car toutes les réponses utilisent soit ForEach-Object, qui traitera les éléments un par un (comme xargs -n1) qui obtient le résultat souhaité pour les exemples donnés, ou stocke le résultat intermédiaire dans une variable, ce qui offense ma ligne de commande fonctionnelle-fu.

32
simonwo

Il y a deux façons que j'ai trouvées. Le premier est probablement PowerShell plus idiomatique, et le second est plus fidèle à l'esprit de pipe de xargs.

Par exemple, disons que nous voulons transmettre toutes nos photos de chats à myapp.exe.

Méthode n ° 1: substitution de commande

Vous pouvez faire quelque chose de similaire à l'utilisation de $ (substitution de commande) dans sh en incorporant votre pipeline dans la chaîne de commande:

&"myapp.exe" @(Get-ChildItem -Recurse -Filter *.jpg | Another-Step)

La @(...) crée un tableau à partir de la commande qu'elle contient et PowerShell étend automatiquement les tableaux passés à & En paramètres de ligne de commande séparés.

Cependant, cela ne répond pas vraiment à la question, car cela ne fonctionnera que si vous avez le contrôle sur la commande à laquelle vous souhaitez passer, ce qui peut ne pas être le cas.

Méthode n ° 2: véritable tuyauterie

Vous pouvez également construire un "double pipeline" en ayant une sous-expression pour diriger vos objets, en les collectant dans un tableau, puis en redirigeant le tableau vers votre commande finale.

,@(Get-ChildItem -Recurse -Filter *.jpg | Another-Step) | %{&"myapp.exe" $_}

La @(...) comme précédemment recueille les éléments dans un tableau, puis le tableau est redirigé vers la commande finale qui est invoquée à l'aide de % (ForEach-Object). Normalement, cela bouclerait ensuite chaque élément individuellement, car PowerShell aplatirait automatiquement le tableau lorsqu'il est canalisé, mais cela peut être évité en ajoutant l'opérateur ,. La variable spéciale $_ Est ensuite utilisée normalement pour incorporer le tableau transmis.

La clé consiste donc à encapsuler le pipeline que vous souhaitez collecter dans ,@(...), puis à le diriger vers quelque chose dans %{...}.

27
simonwo