linux - ¿Cómo puedo usar comandos con alias con xargs?
xargs rm (6)
Tengo el siguiente alias en mis .aliases:
alias gi grep -i
y quiero buscar foo
sin distinción de mayúsculas y minúsculas en todos los archivos que tienen la bar
cadena en su nombre:
find -name /*bar/* | xargs gi foo
Esto es lo que obtengo:
xargs: gi: No such file or directory
¿Hay alguna forma de usar alias en xargs, o tengo que usar la versión completa?
find -name /*bar/* | xargs grep -i foo
Nota: Este es un ejemplo simple. Además de gi
tengo algunos alias bastante complicados que no puedo expandir manualmente tan fácilmente.
Edición: usé tcsh
, así que especifique si una respuesta es específica de shell.
Al usar Bash, también puede especificar el número de argumentos que se pasan 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
(debería funcionar para tcsh de una manera similar)
# alias definition in ~/.tcshrc
echo arg1 arg2 | xargs -n 1 tcsh -cim ''myFuncOrAlias "$1"'' arg0 # untested
Esto es seguro de caracteres especiales:
find . -print0 | xargs -0 bash -ic ''echo gi foo "$@"'' --
-print0
y -0
usan cadenas /0
o NUL
-terminadas para que no ocurran cosas extrañas cuando los nombres de los archivos tienen espacios en ellas.
bash
establece el primer argumento después de la cadena de comando en $0
, por lo que le pasamos un argumento ficticio ( --
) para que el primer archivo listado por find
no se consuma en $0
.
Gire "gi" en un script en su lugar
por ejemplo, en /home/$USER/bin/gi
:
#!/bin/sh
exec /bin/grep -i "$@"
No te olvides de marcar el archivo ejecutable.
La sugerencia here es evitar xargs y usar un bucle "while read" en lugar de xargs:
find -name /*bar/* | while read file; do gi foo "$file"; done
Consulte la respuesta aceptada en el enlace anterior para conocer las mejoras para tratar con espacios o nuevas líneas en los nombres de archivo.
Los alias son específicos de shell - en este caso, muy probablemente específicos de bash. Para ejecutar un alias, debe 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 una shell interactiva (y fuentes .bashrc). bash -c cmd ejecuta cmd .
Póngalos juntos: bash -ic cmd ejecuta cmd en un shell interactivo, donde cmd puede ser una función / alias de bash definida en su .bashrc
.
find -name /*bar/* | xargs bash -ic gi foo
deberías hacer lo que quieras
Edición: veo que has etiquetado 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 le dé -f
.
Prueba esto:
find -name /*bar/* | xargs tcsh -c gi foo
Funcionó para mis pruebas básicas.
Para tcsh (que no tiene funciones), podría usar:
gi foo `find -name "*bar*"`
Para bash / ksh / sh, puede crear una función en el shell.
function foobar
{
gi $1 `find . -type f -name "*"$2"*"`
}
foobar foo bar
Recuerde que usar backquotes en el shell es más ventajoso que usar xargs desde múltiples perspectivas. Coloque la función en su .bashrc.