Bash 4.2 sur CentOS 6.5:
Dans mon, ~/.bash_profile
j'ai un tas d'alias, y compris:
alias grep='grep -n --color=always'
afin que je puisse obtenir la surbrillance des couleurs et imprimer automatiquement les numéros de ligne lors de l'exécution grep
. Si je lance ce qui suit, la mise en surbrillance fonctionne comme prévu:
$ grep -Re 'regex_here' *.py
Cependant, quand je l'ai exécuté récemment:
$ find . -name '*.py' | xargs grep -E 'regex_here'
les résultats n'étaient pas mis en surbrillance et les numéros de ligne n'étaient pas imprimés, me forçant à revenir en arrière et à ajouter explicitement -n --color=always
à la grep
commande.
- Ne
xargs
lit pas les alias dans l'environnement? - Sinon, existe-t-il un moyen de le faire?
xargs
commande. Ce que j'essaie de savoir, c'est s'il y a un moyen d'appeler directement mon aliasxargs
.export GREP_OPTIONS='-n --color=always'
avant votre commande xargs?.bash_profile
. N'hésitez pas à rédiger une réponse ...Réponses:
Un alias est interne au shell où il est défini. Il n'est pas visible pour les autres processus. Il en va de même pour les fonctions shell.
xargs
est une application distincte, qui n'est pas un shell, donc n'a pas de concept d'alias ou de fonctions.Vous pouvez faire en sorte que xargs invoque un shell au lieu d'invoquer
grep
directement. Cependant, l'invocation d'un shell ne suffit pas, vous devez également définir l'alias dans ce shell. Si l'alias est défini dans votre.bashrc
, vous pouvez source ce fichier; cependant, cela peut ne pas fonctionner, vous.bashrc
effectuez d'autres tâches qui n'ont pas de sens dans un shell non interactif.Méfiez-vous des subtilités des citations imbriquées lors de la frappe de l'expression rationnelle. Vous pouvez simplifier votre vie en passant l'expression rationnelle en tant que paramètre au shell.
Vous pouvez effectuer la recherche d'alias de manière explicite. Alors
xargs
verragrep -n --color=always
.En zsh:
Soit dit en passant, il se
find … | xargs …
casse les noms de fichiers contenant des espaces (entre autres) . Vous pouvez résoudre ce problème en modifiant les enregistrements délimités par des valeurs nulles:ou en utilisant
-exec
:Au lieu d'appeler
find
, vous pouvez tout faire entièrement à l'intérieur du shell. Le modèle glob**/
parcourt les répertoires de manière récursive. Dans bash, vous devez d'abord exécutershopt -s globstar
ce modèle global.Cela a quelques limitations:
**/
reproduit en liens symboliques vers des répertoires.Une autre approche consiste à utiliser la substitution de processus, comme suggéré par MariusMatutiae .
Ceci est utile lorsque cela
**/
ne s'applique pas: pour lesfind
expressions complexes , ou en bash ≤4,2 lorsque vous ne voulez pas récuser sous des liens symboliques. Notez que cela rompt sur les noms de fichiers contenant des espaces; une solution consiste à définirIFS
et désactiver la globalisation , mais cela commence à devenir un peu complexe:la source
Utilisation
alias xargs='xargs '
la source
sudo
…Veuillez prendre cela comme une démonstration d'une autre approche, que je ne trouve pas dans la question SO correspondante :
Vous pouvez écrire une fonction wrapper pour
xargs
laquelle vérifie si le premier argument est un alias et si c'est le cas, développez-le en conséquence.Voici un code qui fait exactement cela mais malheureusement, il nécessite le shell Z et ne s'exécute donc pas 1: 1 avec bash (et franchement, je n'ai pas l'habitude de bash assez pour le porter):
Preuve que ça marche:
la source
Une solution plus simple et plus élégante consiste à utiliser la substitution de processus :
Il ne crée pas un nouveau shell comme le fait le tuyau, ce qui signifie que vous êtes toujours dans votre shell d'origine où l'alias est défini, et la sortie est exactement ce que vous souhaitez qu'elle soit.
Faites juste attention à ne laisser aucun espace entre la redirection et les parenthèses, sinon bash générera une erreur. À ma connaissance, la substitution de processus est prise en charge par Bash, Zsh, Ksh {88,93}, mais pas par pdksh (on me dit que cela ne devrait pas encore l'être ).
la source
find
commandes complexes , bien que vous deviez prendre garde qu'elle ne se brisera pas sur les espaces, et cela ne peut pas être corrigé aussi facilement quefind | xargs
possible (en basculant vers-print0
et-0
, ou en utilisant-exec
). Le cas échéant,**/
est plus simple et plus robuste.grep lira un ensemble d'options par défaut à partir de la variable d'environnement GREP_OPTIONS. Si vous voulez mettre
dans votre .bashrc, la variable sera transmise aux sous-coquilles et vous obtiendrez les résultats attendus.
la source
--line-number
ou--color=always
àGREP_OPTIONS
moins que ce soit pour une seule commande, cela cassera beaucoup de scripts.--color=auto
c'est bien d'y avoir, et c'est à peu près tout. Mettre cette ligne dans votre.bashrc
volonté cassera beaucoup de choses./etc/init.d/cron
de mon système:value=`egrep "^${var}=" "$ENV_FILE" | tail -n1 | cut -d= -f2`
. Ou de/usr/bin/pdfjam
:pdftitl=`printf "%s" "$PDFinfo" | grep -e … | sed -e …`
. Un alias n'est pas un problème car il n'est pas vu dans les scripts.GREP_OPTIONS
rompt très mal la prévisibilité, à l'exception de quelques options comme--color=auto
(pour lesquelles il a été conçu).