How can I use aliased commands with xargs?

大兔子大兔子 提交于 2019-11-29 22:59:44

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.

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.

Pete TerMaat

The suggestion here is to avoid xargs and use a "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 refinements to deal with spaces or newlines in filenames.

This is special-character safe:

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

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

bash sets the first argument after the command string as $0, so we pass it a dummy argument (--) so that the first file listed by find doesn't get consumed by $0.

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.

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

The simplest solution in you case would be to expand your alias inline. But that is valid for csh/tcsh only.

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

for bash it will be more tricky, not so handy but still might be useful:

find -name \*bar\* | xargs `alias gi | cut -d "'" -f2` foo
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!