Comment fusionner et canaliser les résultats de deux commandes différentes en une seule commande?

28

Je veux fusionner (union) les sorties de deux commandes différentes et les diriger vers une seule commande.

Un exemple stupide:

Commandes Je veux fusionner le résultat:

cat wordlist.txt
ls ~/folder/*

dans:

wc -l

Dans cet exemple, si wordlist.txt contient 5 lignes et 3 fichiers, je souhaite que wc -l renvoie 8.

$cat wordlist.txt *[magical union thing]* ls ~/folder/* | wc -l
8

Comment puis-je le faire?

    
posée David Oneill 07.05.2012 - 21:05
la source

3 réponses

42

Votre truc d'union magique est un point-virgule ... et des accolades:

    { cat wordlist.txt ; ls ~/folder/* ; } | wc -l

Les parenthèses ne regroupent que les commandes, de sorte que le signe de tube | affecte la sortie combinée.

Vous pouvez également utiliser la parenthèse () autour d'un groupe de commandes, qui exécuterait les commandes dans un sous-shell. Ceci a un ensemble subtil de différences avec des accolades, par ex. essayez ce qui suit:

    cd $HOME/Desktop ; (cd $HOME ; pwd) ; pwd
    cd $HOME/Desktop ; { cd $HOME ; pwd ; } ; pwd

Vous verrez que toutes les variables d'environnement, y compris le répertoire de travail en cours, sont réinitialisées après avoir quitté le groupe de parenthèses, mais pas après avoir quitté le groupe d'accolades.

Comme pour le point-virgule, les alternatives incluent les signes && et || , qui exécutent conditionnellement la deuxième commande uniquement si la première est réussie ou non, respectivement, par exemple

    cd $HOME/project && make
    ls $HOME/project || echo "Directory not found."
    
réponse donnée pablomme 07.05.2012 - 21:09
la source
8

Comme wc accepte un chemin de fichier en entrée, vous pouvez également utiliser la substitution de processus:

wc -l <(cat wordlist.txt; ls ~/folder/*)

Cela équivaut à peu près à:

echo wordlist.txt > temp
ls ~/folder/* >> temp
wc -l temp

Notez que ls ~/folder/* renvoie également le contenu des sous-répertoires, le cas échéant (en raison de l'expansion des globes). Si vous voulez simplement lister le contenu de ~/folder , utilisez simplement ls ~/folder .

    
réponse donnée Lekensteyn 07.05.2012 - 21:10
la source
1

Je me posais la même question et finis par écrire un court script.

magicalUnionThing (je l'appelle append ):

#!/bin/sh
cat /dev/stdin
$*

Rendre ce script exécutable

chmod +x ./magicalUnionThing

Maintenant vous faites

cat wordlist.txt |./magicalUnionThing ls ~/folder/* | wc -l

Que fait-il?

  • Envoyer une entrée standard à la sortie standard
  • Exécuter l'argument $* renvoie tous les arguments sous forme de chaîne. La sortie de cette commande va à la sortie standard du script par défaut.

La sortie de magicalUnionThing sera donc sa stdin + stdout de la commande passée en argument.

Il existe bien sûr des moyens plus simples, comme d’autres réponses.
Peut-être que cette alternative peut être utile dans certains cas.

    
réponse donnée Rolf 11.03.2018 - 12:17
la source

Lire d'autres questions sur les étiquettes