2009-06-11 13 views
23

Tengo el siguiente alias en mis .aliases:¿Cómo puedo usar comandos con alias con xargs?

alias gi grep -i 

y quiero buscar foo mayúsculas y minúsculas en todos los archivos que tienen la cadena bar en su nombre:

find -name \*bar\* | xargs gi foo 

Este es lo que me sale:

xargs: gi: No such file or directory 

¿hay alguna manera de utilizar los alias de xargs, o tengo que utilizar la versión completa:

find -name \*bar\* | xargs grep -i foo 

Nota: Este es un ejemplo sencillo. Además de gi tengo algunos alias bastante complicados que no puedo expandir manualmente tan fácilmente.

Edit: He usado tcsh, así que por favor especifique si la respuesta es específica del shell.

+0

Aquí hay una pregunta similar (aunque no idéntica): http://stackoverflow.com/questions/513611/xargs-doesnt-recognize-bash-aliases –

Respuesta

22

Los alias son específicos de shell; en este caso, lo más probable es que sean específicos de bash. Para ejecutar un alias, necesita ejecutar bash, pero los alias solo se cargan para shells interactivos (más precisamente, .bashrc solo se leerá para un shell interactivo).

bash -i ejecuta un shell interactivo (y fuentes .bashrc). bash -c cmd ejecuta cmd.

Póngalos juntos: de bash -ic cmd carreras cmd en un shell interactivo, donde cmd puede ser una función bash/alias definido en su .bashrc.

find -name \*bar\* | xargs bash -ic gi foo 

debe hacer lo que desee.

Editar: Veo que etiquetó la pregunta como "tcsh", por lo que la solución específica de bash no es aplicable. Con tcsh, no necesita el -i, ya que parece leer .tcshrc a menos que proporcione -f.

Prueba esto:

find -name \*bar\* | xargs tcsh -c gi foo 

funcionó para mi prueba básica.

+0

Consulte [esta respuesta] (http://stackoverflow.com/a/40912257/5353461) si desea comportarse bien con archivos que incluyen espacios en blanco. –

7

Turn "gi" en una secuencia de comandos en lugar

por ejemplo, en /home/$USER/bin/gi:

#!/bin/sh 
exec /bin/grep -i "[email protected]" 

no se olvide de marcar el archivo ejecutable.

5

La sugerencia es evitar here xargs y utilizar un bucle "mientras se lee" en lugar de xargs:

find -name \*bar\* | while read file; do gi foo "$file"; done 

Véase la respuesta aceptada en el enlace anterior para refinamientos para hacer frente a los espacios o saltos de línea en los nombres de archivo.

+0

Si los nombres de los archivos tienen espacios en blanco o líneas nuevas, esto no es tan bueno. como xargs con la opción -0 (y encontrar con -print0). –

+0

Gracias, lo edité para señalarlo. –

0

Para tcsh (que no tiene funciones), se puede utilizar:

gi foo `find -name "*bar*"` 

Para bash/ksh/sh, puede crear una función en la cáscara.

function foobar 
    { 
     gi $1 `find . -type f -name "*"$2"*"` 
    } 

    foobar foo bar 

Recuerde que el uso de comillas inversas en la cáscara es más ventajoso que el uso de xargs desde múltiples perspectivas. Coloque la función en su .bashrc.

0

Usando Bash también puede especificar el número de argumentos que se pasa a su alias (o función) de esta manera:

alias myFuncOrAlias='echo' # alias defined in your ~/.bashrc, ~/.profile, ... 
echo arg1 arg2 | xargs -n 1 bash -cil 'myFuncOrAlias "$1"' arg0 

(debe trabajar para Tcsh de manera similar)

# alias definition in ~/.tcshrc 
echo arg1 arg2 | xargs -n 1 tcsh -cim 'myFuncOrAlias "$1"' arg0 # untested 
0

se trata de caracteres especiales seguros:

find . -print0 | xargs -0 bash -ic 'echo gi foo "[email protected]"' -- 

El -print0 y -0 uso \0 o NUL -cadenas terminadas para que no ocurra nada extraño cuando los nombres de archivo tienen espacios en ellas.

bash establece el primer argumento después de la cadena de comandos como $0, por lo que pasarle un argumento ficticio (--) de manera que el primer archivo que aparece por find no quede consumido por $0.

Cuestiones relacionadas