tags:

views:

712

answers:

5

I have the following alias in my .aliases:

alias gi grep -i

and I want to look for foo case-insensitively in all the files that have the string bar in their name:

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

This is what I get:

xargs: gi: No such file or directory

Is there any way to use aliases in xargs, or do I have to use the full version:

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

Note: This is a simple example. Besides gi I have some pretty complicated aliases that I can't expand manually so easily.

Edit: I used tcsh, so please specify if an answer is shell-specific.

+4  A: 

Turn "gi" into a script instead

eg, in /home/$USER/bin/gi:

#!/bin/sh
exec /bin/grep -i "$@"

don't forget to mark the file executable.

Peter Ericson
+1  A: 

The suggestion here is to avoid xargs and use a "while read" loop.

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

See the accepted answer in the link above for refinements to deal with spaces or newlines in filenames.

Pete TerMaat
If file names have blanks or newlines in them, this is not as good as xargs with -0 option (and find with -print0).
Jonathan Leffler
Thanks, I edited to point that out.
Pete TerMaat
+6  A: 

Aliases are shell-specific - in this case, most likely bash-specific. To execute an alias, you need to execute bash, but aliases are only loaded for interactive shells (more precisely, .bashrc will only be read for an interactive shell).

bash -i runs an interactive shell (and sources .bashrc). bash -c cmd runs cmd.

Put them together: bash -ic cmd runs cmd in an interactive shell, where cmd can be a bash function/alias defined in your .bashrc.

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

should do what you want.

Edit: I see you've tagged the question as "tcsh", so the bash-specific solution is not applicable. With tcsh, you dont need the -i, as it appears to read .tcshrc unless you give -f.

Try this:

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

It worked for my basic testing.

camh
A: 

For tcsh (which does not have functions), you could use:

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

For bash/ksh/sh, you can create a function in the shell.

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

   foobar foo bar

Remember that using backquotes in the shell is more advantageous than using xargs from multiple perspectives. Place the function in your .bashrc.

Ryan Oberoi
A: 

Using Bash you may also specify the number of args being passed to your alias (or function) like so:

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

(should work for tcsh in a similar way)

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