31

我的 .aliases 中有以下别名:

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 的。

4

8 回答 8

33

别名是特定于 shell 的——在这种情况下,很可能是特定于 bash 的。要执行别名,您需要执行 bash,但别名仅为交互式 shell 加载(更准确地说,.bashrc只会为交互式 shell 读取)。

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

将它们放在一起: bash -ic cmd在交互式 shell 中运行cmd ,其中cmd可以是 .bashrc 中定义的 bash 函数/别名.bashrc

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

应该做你想做的。

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

试试这个:

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

它适用于我的基本测试。

于 2009-06-11T06:38:02.390 回答
8

将“gi”改为脚本

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

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

不要忘记将文件标记为可执行文件。

于 2009-06-11T05:39:30.567 回答
6

这里的建议是避免使用 xargs 并使用“while read”循环而不是 xargs:

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

有关处理文件名中的空格或换行符的改进,请参阅上面链接中接受的答案。

于 2009-06-11T05:40:12.797 回答
6

这个解决方案在 bash 中非常适合我:
https ://unix.stackexchange.com/a/244516/365245

问题

[~]: alias grep='grep -i'
[~]: find -maxdepth 1 -name ".bashrc" | xargs grep name      # grep alias not expanded
[~]: ### no matches found ###

解决方案

[~]: alias xargs='xargs ' # create an xargs alias with trailing space
[~]: find -maxdepth 1 -name ".bashrc" | xargs grep name     # grep alias gets expanded
# Name     : .bashrc

为什么有效

[~]: man alias  
alias: alias [-p] [name[=value] ... ]  
(snip)  
A trailing space in VALUE causes the next word to be checked for
alias substitution when the alias is expanded.
于 2020-01-21T13:40:37.310 回答
2

这是特殊字符安全的:

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

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

bash将命令字符串之后的第一个参数设置为$0,因此我们将其传递给一个虚拟参数 ( --),以便 列出的第一个文件find不会被$0.

于 2016-12-01T13:43:54.487 回答
0

对于 tcsh (没有功能),您可以使用:

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

对于 bash/ksh/sh,您可以在 shell 中创建一个函数。

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

   foobar foo bar

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

于 2009-06-11T07:20:01.683 回答
0

使用 Bash,您还可以指定传递给别名(或函数)的参数数量,如下所示:

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
于 2010-07-19T10:20:04.400 回答
0

在您的情况下,最简单的解决方案是扩展您的别名内联。但这仅对 csh/tcsh 有效。

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

对于 bash 它会更棘手,不是那么方便,但仍然可能有用:

find -name \*bar\* | xargs `alias gi | cut -d "'" -f2` foo
于 2019-08-27T10:20:12.353 回答