How can I use aliased commands with xargs?

I have the following alias in my .aliases:

alias gi grep -i 

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

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

This is what I get:

 xargs: gi: No such file or directory 

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

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

Note. . This is a simple example. Other than gi , I have some pretty complex aliases that I cannot manually expose so easily.

Edit: I used tcsh , so please indicate if the answer is shell specific.

+26
linux tcsh xargs
Jun 11 '09 at 5:23
source share
7 answers

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

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

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

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

should do what you want.

Edit: I see that you marked the question as "tcsh", so the bash special solution is not applicable. With tcsh, you don't need -i since it seems to read .tcshrc unless you give -f .

Try the following:

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

It worked for my core testing.

+30
Jun 11 '09 at 6:38
source share

Turn "gi" into a script instead

e.g. in /home/$USER/bin/gi :

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

do not forget to mark the executable file.

+7
Jun 11 '09 at 5:39
source share

The suggestion here is to avoid xargs and use a while while read loop instead of xargs:

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

See the accepted answer in the link above for details regarding spaces or newlines in file names.

+6
Jun 11 '09 at 5:40
source share

This is safe for special characters:

 find . -print0 | xargs -0 bash -ic 'echo gi foo "$@"' -- 

-print0 and -0 use \0 or NUL -termined strings, so you don't get weird things when filenames have spaces in them.

bash sets the first argument after the command line as $0 , so we pass it a dummy argument ( -- ), so the first file specified in find is not consumed $0 .

+1
Dec 01 '16 at 13:43
source share

For tcsh (which has no functions) you can 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 a shell is more beneficial than using xargs from multiple perspectives. Put the function in your .bashrc.

0
Jun 11 '09 at 7:20
source share

Using Bash, you can also specify the number of arguments passed to your alias (or function), for example:

 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 
0
Jul 19 '10 at 10:20
source share

The easiest solution in your case would be to expand the built-in alias. But this is true only for csh / tcsh.

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

for bash it will be more complicated, not so convenient, but it can still be useful:

 find -name \*bar\* | xargs 'alias gi | cut -d "'" -f2' foo 
0
Aug 27 '19 at 10:20
source share



All Articles