如何将别名命令与 xargs 一起使用?

发布于 2024-07-24 06:17:59 字数 541 浏览 10 评论 0原文

我的 .aliases 中有以下别名:

alias gi grep -i

并且我想在名称中包含字符串 bar 的所有文件中不区分大小写地查找 foo

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

这就是我得到:

xargs: gi: No such file or directory

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

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

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

编辑:我使用了tcsh,因此请指定答案是否特定于 shell。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

旧时浪漫 2024-07-31 06:17:59

别名是特定于 shell 的 - 在本例中,很可能是特定于 bash 的。 要执行别名,您需要执行 bash,但只有交互式 shell 才会加载别名(更准确地说,只有交互式 shell 才会读取 .bashrc)。

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

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

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

应该做你想做的事。

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

试试这个:

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

它对我的基本测试有效。

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.

风筝有风,海豚有海 2024-07-31 06:17:59

这个解决方案在 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.

This solution worked perfect for me in bash:
https://unix.stackexchange.com/a/244516/365245

Problem

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

Solution

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

Why it works

[~]: 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.
孤寂小茶 2024-07-31 06:17:59

将“gi”转为脚本

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

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

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

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.

孤独患者 2024-07-31 06:17:59

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

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

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

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.

拿命拼未来 2024-07-31 06:17:59

这是特殊字符安全的:

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

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

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

This is special-character safe:

find . -print0 | xargs -0 bash -ic '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.

℡Ms空城旧梦 2024-07-31 06:17:59

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

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

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

find -name \*bar\* | xargs `alias gi | cut -d "'" -f2` foo

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
开始看清了 2024-07-31 06:17:59

对于 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 中。

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.

怕倦 2024-07-31 06:17:59

使用 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

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
洒一地阳光 2024-07-31 06:17:59

在使用 xargs 尝试了许多对我不起作用的解决方案后,我选择了带有循环的替代方案,请参阅下面的示例:

for file in $(git ls-files *.txt); do win2unix $file; done
for file in $(find . -name *.txt); do win2unix $file; done

将生成文件列表的表达式放入 $()< /code> 如上面的示例所示。 我使用了 win2unix,它是我的 .bashrc 中的一个函数,它获取文件路径并将其转换为 Linux 结尾。 希望别名也能工作。

请注意,我的路径或文件名中没有空格。

After trying many solutions with xargs that didn't work for me, went for an alternative with a loop, see examples below:

for file in $(git ls-files *.txt); do win2unix $file; done
for file in $(find . -name *.txt); do win2unix $file; done

Put your expression that generates a list of files inside $() as in the examples above. I've used win2unix which is a function in my .bashrc that takes a file path and converts it to Linux endings. Would expect aliases to also work.

Note that I did not have spaces in my paths or filenames.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文