2009-06-11 52 views
23

我在.aliases以下别名:如何在xargs中使用别名命令?

alias gi grep -i 

,我想寻找foo不区分大小写在所有具有串bar在他们的名字的文件:

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

这是我所得到的:

xargs: gi: No such file or directory 

有没有办法在xargs的使用别名,或做我必须使用完整版本:

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

注意:这是一个简单的例子。除了gi我还有一些非常复杂的别名,我无法如此轻松地进行手动扩展。

编辑:我用tcsh,所以请指定一个答案是否是特定于shell的。

+0

下面是一个类似的(虽然不完全相同)的问题:http://stackoverflow.com/questions/513611/xargs-doesnt-recognize-bash-aliases – 2010-03-08 12:07:48

回答

22

别名是shell特有的 - 在这种情况下,最有可能是bash特有的。要执行别名,您需要执行bash,但仅针对交互式shell加载别名(更精确地说,.bashrc只能在交互式shell中读取)。

bash -i运行交互式shell(和源.bashrc)。 bash -c cmd运行cmd

把它们放在一起: 庆典-IC CMD运行CMD在一个交互的shell,其中CMD可以在你的.bashrc定义的bash函数/别名。

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

应该做你想做的。

编辑:我看你已经将问题标记为“tcsh”,所以特定于bash的解决方案不适用。有了tcsh,你不需要-i,因为它似乎读取.tcshrc,除非你给-f

试试这个:

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

它的工作对我的基本测试。

7

转向 “GI” 为脚本,而不是

例如,在/home/$USER/bin/gi

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

不要忘记标记文件的可执行文件。

5

的建议here是为了避免和xargs的使用“而改为”循环代替的xargs:

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

见接受的答案在上面的改进处理文件名中使用空格或换行符的链接。

+0

如果文件名中有空格或换行符,这不是很好作为带-0选项的xargs(并使用-print0查找)。 – 2009-06-11 06:10:18

+0

谢谢,我编辑指出。 – 2009-06-11 14:05:59

0

对于tcsh(不具备的功能),你可以使用:

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

对于bash/KSH/sh的,你可以创建在外壳的功能。

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

    foobar foo bar 

请记住,在shell中使用反引号比从多个角度使用xargs更有优势。将函数放在你的.bashrc中。

0

使用bash,你也可以指定args来数被传递给你的别名(或功能),像这样:

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

(应为tcsh的工作以类似的方式)

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

这是特殊字符安全:

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

-print0-0使用\0NUL - 终止的字符串,因此当文件名中有空格时不会发生奇怪的事情。

bash设置命令字符串作为$0后的第一个参数,所以我们传递一个伪参数(--),以便通过find列出的第一个文件没有得到通过$0消耗。