Un alias es interno al shell donde se define. No es visible para otros procesos. Lo mismo ocurre con las funciones de shell. xargs
es una aplicación separada, que no es un shell, por lo que no tiene un concepto de alias o funciones.
Puede hacer que xargs invoque un shell en lugar de invocarlo grep
directamente. Sin embargo, invocar un shell no es suficiente, también debe definir el alias en ese shell. Si el alias está definido en su .bashrc
, puede obtener ese archivo; sin embargo, esto puede no funcionar, .bashrc
realiza otras tareas que no tienen sentido en un shell no interactivo.
find . -name '*.py' | xargs bash -c '. ~/.bashrc; grep -E regex_here "$@"' _
Tenga cuidado con las complejidades de las citas anidadas al escribir la expresión regular. Puede simplificar su vida pasando la expresión regular como parámetro al shell.
find . -name '*.py' | xargs bash -c '. ~/.bashrc; grep -E "$0" "$@"' regex_here
Puede realizar la búsqueda de alias explícitamente. Entonces xargs
ya veremos grep -n --color=always
.
find . -name '*.py' | xargs "${BASH_ALIASES[grep]}" regex_here
En zsh:
find . -name '*.py' | xargs $aliases[grep] regex_here
Por cierto, tenga en cuenta que se find … | xargs …
rompe en los nombres de archivo que contienen espacios (entre otros) . Puede solucionar esto cambiando a registros delimitados por nulos:
find . -name '*.py' -print0 | xargs -0 "${BASH_ALIASES[grep]}" regex_here
o usando -exec
:
find . -name '*.py' -exec "${BASH_ALIASES[grep]}" regex_here {} +
En lugar de llamar find
, puede hacer todo por completo dentro del shell. El patrón global **/
atraviesa directorios de forma recursiva. En bash, shopt -s globstar
primero debe ejecutar para habilitar este patrón global.
grep regex_here **/*.py
Esto tiene algunas limitaciones:
- Si coinciden muchos archivos (o si tienen rutas largas), el comando puede fallar porque excede la longitud máxima de la línea de comando.
- En bash ≤4.2 (pero no en versiones más recientes, ni en ksh o zsh), se
**/
repite en enlaces simbólicos a directorios.
Otro enfoque es utilizar la sustitución de procesos, como lo sugiere MariusMatutiae .
grep regex_here <(find . -name '*.py')
Esto es útil cuando **/
no es aplicable: para find
expresiones complejas , o en bash ≤4.2 cuando no desea recurrir bajo enlaces simbólicos. Tenga en cuenta que esto se rompe en los nombres de archivos que contienen espacios; Una solución alternativa es establecer IFS
y deshabilitar el globbing , pero está empezando a ser un poco complejo:
(IFS=$'\n'; set -f; grep regex_here <(find . -name '*.py') )