web-dev-qa-db-fra.com

Comment utiliser la sortie de grep en tant que chemin pour cd?

Comment puis-je diriger la sortie de grep en tant qu'argument de la commande cd?

Par exemple:

[root@xxx xxx]# pip install Django | grep '/usr.*'  
Requirement already satisfied (use --upgrade to upgrade): Django in   /usr/lib64/python2.7/site-packages

Ici /usr/lib64/python2.7/site-packages est mis en surbrillance et je souhaite transmettre cette chaîne à cd.

9
micgeronimo

Utilisez la substitution de commande de Bash $(), vous avez également besoin de -o avec grep pour sélectionner uniquement la partie correspondante:

cd "$(pip install Django | grep -o '/usr.*')"

Notez que même si vous vous échapperez dans ce cas, mais que vous devriez toujours inclure la substitution de commande entre guillemets afin que le shell n'exécute pas le fractionnement des mots sur les espaces. (par défaut, espace, tabulation et nouvelle ligne, dépend de la variable IFS dans le cas de bash).

16
heemayl

Selon ce que vous faites et ne savez pas à l'avance sur ce que pip produira, vous pourriez décider de grep pour autre chose que /usr.*.

Si vous connaissez le répertoire commence par /usr (et qu'il apparaît à la fin de la ligne de sortie de pip, et que /usr n'apparaît nulle part sur la ligne précédant le nom du répertoire), c'est un choix judicieux; la réponse de heemayl vous dit comment.

Si la raison vous savez qu'elle commence par /usr c'est que vous venez d'exécuter la commande et que vous connaissez le répertoire que vous souhaitez modifier, je suggère la solution plus simple consistant à exécuter la commande cd /usr/lib64/python2.7/site-packages. C’est moins de frappe même si vous n’utilisez pas complétion par des tabulations .

Sinon, vous pourriez choisir une expression rationnelle différente selon ce que vous savez sur le résultat analysé. Toutes les alternatives ci-dessous supposent toujours que le nom du répertoire apparaît à la fin de la ligne, mais les autres hypothèses varient.

Si vous connaissez le nom du répertoire est absolu (c’est-à-dire, commence par un /) et non / apparaît sur la ligne précédant le nom du répertoire , vous pouvez utiliser la même expression rationnelle que celle utilisée dans réponse de heemayl mais avec / au lieu de /usr:

cd "$(pip install Django | grep -o '/.*')"

Cela correspond à un / suivi d'un zéro ou plus (*) de n'importe quel caractère (.).

Si vous connaissez , le nom du répertoire ne contient aucun espace horizontal (aucun espace ni aucune tabulation) et apparaît à la fin du champ. ligne , vous pouvez utiliser:

cd "$(pip install Django | grep -oP '[^\h]+$')"

Ici, j’ai utilisé ne expression rationnelle Perl (-P), car l’abréviation \h (pour [:blank:]) facilite la saisie et la lecture par rapport à une extension étendue. expression rationnelle (-E). Ceci correspond à un ou plusieurs (+) de n'importe quel caractère d'une classe de caractères ([]) qui est not ​​(^) a espace ou tabulation (\h).

Si vous connaissez t , le nom du répertoire est immédiatement précédé de in entouré de blancs horizontaux (c'est-à-dire, complété à gauche et à droite par blancs), et que c’est la seule occurrence de ce type de in sur la ligne , vous pouvez utiliser:

cd "$(pip install Django | grep -oP '\hin\h+\K.+')"

Cela utilise une assertion de recherche positive de largeur nulle (\K) pour faire correspondre un ou plusieurs caractères (.+) qui apparaissent après un espace ou une tabulation (\h), in, et un autre ou plusieurs espaces ou tabulations (\h+), sans inclure réellement in et les espaces vides qui l'entourent dans la correspondance. Assertions de contournement sont une caractéristique des expressions rationnelles Perl.

Le modèle \h+in\h+\K.+ aurait également fonctionné, mais il suffit de rechercher un blanc avant in, quel que soit le nombre de caractères présents. En revanche, nous devons faire correspondre all les blancs après in, sinon ils ne seraient pas ignorés par \K et ils seraient appariés dans le nom du répertoire.

Si vous connaissez le nom du répertoire est immédiatement précédé de la dernière occurrence de la ligne = de in, suivie d'un espace horizontal , vous pouvez utiliser:

set +H
cd "$(pip install Django | grep -oP '\hin\h+(?!.*\hin\h.*)\K.*')"
set -H

Là, l'assertion de recherche positive de largeur zéro contient elle-même une assertion de recherche d'anticipation négative de largeur ((?!)).

Le ! apparaît de manière à être difficile pour échapper avec élégance; la méthode que j'ai utilisée pour l'empêcher de déclencher Shell expansion de l'historique avant d'être transmise à grep consiste à désactiver temporairement l'expansion de l'historique (set +H) avant d'exécuter la commande et de la réactiver. il (set -H) ensuite. Si vous utilisez cela dans un script et que votre script ne contient pas set -H, vous n'avez pas besoin de le faire, car le développement de l'historique est activé automatiquement uniquement lorsqu'un shell s'exécute de manière interactive.

Enfin, notez qu'aucun de ceux-ci, ni réponse de heemayl , ne dirige en fait la sortie de grep vers cd (bien que la sortie de pip est toujours connecté à grep). Plutôt que tubes , l'outil approprié pour ce travail est substitution de commande .

9
Eliah Kagan