您可以使用find
和xargs
这样的一些实现来执行以下操作。
$ find . -type f -print0 | xargs -r0 ./myscript
或者,通常,只是find
:
$ find . -type f -exec ./myscript {} +
例
说我有以下示例目录。
$ tree
.
|-- dir1
| `-- a\ file1.txt
|-- dir2
| `-- a\ file2.txt
|-- dir3
| `-- a\ file3.txt
`-- myscript
3 directories, 4 files
现在假设我有这个./myscript
。
#!/bin/bash
for i in "$@"; do
echo "file: $i"
done
现在,当我运行以下命令时。
$ find . -type f -print0 | xargs -r0 ./myscript
file: ./dir2/a file2.txt
file: ./dir3/a file3.txt
file: ./dir1/a file1.txt
file: ./myscript
或者当我使用第二种形式时:
$ find . -type f -exec ./myscript {} +
file: ./dir2/a file2.txt
file: ./dir3/a file3.txt
file: ./dir1/a file1.txt
file: ./myscript
细节
查找+ xargs
上面两种方法虽然看起来有所不同,但本质上是相同的。第一种是从find中获取输出,\0
通过-print0
开关使用NULLs()将其拆分。该xargs -0
专门采取输入这是使用NULL的分裂。该非标准语法是GNU引入的find
,xargs
但如今在其他一些语言(如最新的BSD)中也可以找到。如果在GNU中找不到任何东西,而在BSD中却找不到任何东西,-r
则需要使用该选项以避免调用。myscript
find
find
注意:整个方法取决于您永远不会传递太长的字符串的事实。如果是,则将./myscript
启动find 的第二次调用,并从其余的后续结果中开始。
用+查找
这是标准方式(尽管它只是在最近才(2005)才添加到的GNU实现中find
)。xargs
字面上内置了执行我们正在做的事情的能力find
。因此,find
将找到文件列表,然后将该列表传递尽可能多的参数,以适应之后指定的命令-exec
(请注意,在这种情况下{}
只能是最后一个+
),并在需要时多次运行命令。
为什么不报价?
在第一个示例中,我们通过使用NULL分隔参数来完全避免引用问题,从而采取了捷径。当xargs
给出此列表时,它被指示拆分为NULL,以有效保护我们的单个命令原子。
在第二个示例中,我们将结果保留在内部find
,因此它知道每个文件原子是什么,并将保证适当地处理它们,从而避免了引用这些文件的麻烦。
命令行的最大大小?
这个问题会不时出现,因此,作为奖励,我将其添加到此答案中,主要是为了将来我能找到它。您可以xargs
用来查看环境的限制,如下所示:
$ xargs --show-limits
Your environment variables take up 4791 bytes
POSIX upper limit on argument length (this system): 2090313
POSIX smallest allowable upper limit on argument length (all systems): 4096
Maximum length of command we could actually use: 2085522
Size of command buffer we are actually using: 131072
IFS="
,newline,"
)。但是是否需要对所有文件名执行脚本?如果不是,请考虑使用find本身为每个文件执行脚本。