66

我正在尝试运行以下命令:

find . -iname '.#*' -print0 | xargs -0 -L 1 foobar

其中“foobar”是在我的 .bashrc 文件中定义的别名或函数(在我的例子中,它是一个带有一个参数的函数)。显然 xargs 不承认这些是它可以运行的东西。有没有聪明的方法来解决这个问题?

4

6 回答 6

38

既然只有你的交互式 shell 知道别名,为什么不直接运行别名而不通过分叉xargs呢?

find . -iname '.#*' -print0 | while read -r -d '' i; do foobar "$i"; done

如果您确定您的文件名中没有换行符(ick,为什么会这样?),您可以将其简化为

find . -iname '.#*' -print | while read -r i; do foobar "$i"; done

甚至只是find -iname '.#*' | ...,因为默认目录是.并且默认操作是-print.

另一种选择:

 IFS=$'\n'; for i in `find -iname '.#*'`; do foobar "$i"; done

告诉 Bash 单词仅在换行符处拆分(默认值:IFS=$' \t\n')。不过,您应该小心这一点;有些脚本不能很好地应对更改的$IFS.

于 2009-02-04T22:53:22.803 回答
11

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

alias myFuncOrAlias='echo'  # alias defined in your ~/.bashrc, ~/.profile, ...
echo arg1 arg2 | xargs -n 1 bash -cil 'myFuncOrAlias "$1"' arg0
echo arg1 arg2 | xargs  bash -cil 'myFuncOrAlias "$@"' arg0
于 2010-07-19T10:26:21.267 回答
6

在被别名的命令中添加尾随空格会导致其他别名命令扩展:

alias xargs='xargs ' # aliased commands passed to xargs will be expanded

有关更多信息,请参阅此答案:
https ://stackoverflow.com/a/59842439/11873710

于 2020-01-21T14:50:38.460 回答
5

这不起作用,因为xargs期望能够exec程序作为其参数给出。

由于foobar在您的情况下只是一个bash别名或函数,因此没有要执行的程序。

虽然它涉及启动由 .bash返回的每个文件find,但您可以编写一个小的 shell 脚本:

#!/bin/bash
. $(HOME)/.bashrc
func $*

然后将该脚本的名称作为参数传递给xargs

于 2009-02-04T22:18:33.467 回答
1

我通常使用这样的查找:

find . -iname '' -exec cmd '{}' \;

'{}' 将被替换为文件名,而 \; 是终止执行链所必需的。但是,如果这不适用于您的函数,您可能需要通过 bash 运行它:

find .. |sed -e "s/.*/cmd '&'/"|bash

Find 将每个文件打印在一行上,sed 只是在您的命令前面加上前缀,然后将其通过管道传输到 bash 以执行。先跳过|bash 看看会发生什么。

于 2009-02-04T22:16:47.603 回答
0

尝试

find . -iname '.#*' -print0 | xargs -0 -L 1 $(foobar)
于 2018-10-23T11:26:56.197 回答