Bash 如何将/bin/cat的子目录拆分为更小的块

Bash 如何将/bin/cat的子目录拆分为更小的块,bash,cat,Bash,Cat,我有以下情况。一个包含很多子目录的目录,每个子目录都包含一个我想要连接的感兴趣的文件。 e、 g 现在,我尝试使用cat my_dir/*/*/*.txt>all.txt 但不幸的是,子目录树太大,导致以下错误: bash: /bin/cat: Argument list too long 有没有一种巧妙的方法来避免这个问题,例如,将文件连接成更小的块? 例如,连接1/3的子曲面,然后再连接1/3和1/3,然后将它们全部连接在一起?让查找遍历文件,并将尽可能多的子曲面添加到每个cat调用的命令

我有以下情况。一个包含很多子目录的目录,每个子目录都包含一个我想要连接的感兴趣的文件。 e、 g

现在,我尝试使用
cat my_dir/*/*/*.txt>all.txt

但不幸的是,子目录树太大,导致以下错误:

bash: /bin/cat: Argument list too long
有没有一种巧妙的方法来避免这个问题,例如,将文件连接成更小的块?
例如,连接1/3的子曲面,然后再连接1/3和1/3,然后将它们全部连接在一起?

查找
遍历文件,并将尽可能多的子曲面添加到每个
cat
调用的命令行:

find . -type f -name '*.txt' -exec cat '{}' + >all.txt
如果您的
查找
不支持
-exec。。。{}+
(如果符合当前版本的POSIX规范,它应该这样做),还有一种使用GNU扩展使xargs安全的方法:

find . -type f -name '*.txt' -print0 | xargs -0 cat >all.txt
在没有
-0
的情况下使用xargs是不安全的——在这种情况下,它不能正确处理带有换行符的文件名,以及其他问题(其中一些问题可以通过其他选项避免,但并非所有问题)。想想看,一个恶意用户创建了一个文件
$'foo\n/etc/passwd'
——您不想冒着将
/etc/passwd
注入输出的风险

最后,使用
find-exec
(为找到的每个文件调用一个单独的
cat
副本)的方法效率较低,也较旧:

…或者,在类似的情况下(多次调用
cat
),您只需在shell脚本中使用一个循环:

for f in my_dir/*/*/*.txt; do
  cat "$f"
done >all.txt
请注意,这会在整个循环上执行重定向,而不是(效率较低)在每个文件的基础上执行重定向



旁白:如果使用POSIX sh或bash,则不需要引用
{}
。但是,如果试图支持
zsh
,您确实需要引用
{}
,我在这里就是这样做的。

查找
遍历文件,并向每个
cat
调用的命令行添加尽可能多的文件:

find . -type f -name '*.txt' -exec cat '{}' + >all.txt
如果您的
查找
不支持
-exec。。。{}+
(如果符合当前版本的POSIX规范,它应该这样做),还有一种使用GNU扩展使xargs安全的方法:

find . -type f -name '*.txt' -print0 | xargs -0 cat >all.txt
在没有
-0
的情况下使用xargs是不安全的——在这种情况下,它不能正确处理带有换行符的文件名,以及其他问题(其中一些问题可以通过其他选项避免,但并非所有问题)。想想看,一个恶意用户创建了一个文件
$'foo\n/etc/passwd'
——您不想冒着将
/etc/passwd
注入输出的风险

最后,使用
find-exec
(为找到的每个文件调用一个单独的
cat
副本)的方法效率较低,也较旧:

…或者,在类似的情况下(多次调用
cat
),您只需在shell脚本中使用一个循环:

for f in my_dir/*/*/*.txt; do
  cat "$f"
done >all.txt
请注意,这会在整个循环上执行重定向,而不是(效率较低)在每个文件的基础上执行重定向



旁白:如果使用POSIX sh或bash,则不需要引用
{}
。但是,如果试图支持
zsh
,您确实需要引用
{}
,我在这里就是这样做的。

查找
遍历文件,并向每个
cat
调用的命令行添加尽可能多的文件:

find . -type f -name '*.txt' -exec cat '{}' + >all.txt
如果您的
查找
不支持
-exec。。。{}+
(如果符合当前版本的POSIX规范,它应该这样做),还有一种使用GNU扩展使xargs安全的方法:

find . -type f -name '*.txt' -print0 | xargs -0 cat >all.txt
在没有
-0
的情况下使用xargs是不安全的——在这种情况下,它不能正确处理带有换行符的文件名,以及其他问题(其中一些问题可以通过其他选项避免,但并非所有问题)。想想看,一个恶意用户创建了一个文件
$'foo\n/etc/passwd'
——您不想冒着将
/etc/passwd
注入输出的风险

最后,使用
find-exec
(为找到的每个文件调用一个单独的
cat
副本)的方法效率较低,也较旧:

…或者,在类似的情况下(多次调用
cat
),您只需在shell脚本中使用一个循环:

for f in my_dir/*/*/*.txt; do
  cat "$f"
done >all.txt
请注意,这会在整个循环上执行重定向,而不是(效率较低)在每个文件的基础上执行重定向



旁白:如果使用POSIX sh或bash,则不需要引用
{}
。但是,如果试图支持
zsh
,您确实需要引用
{}
,我在这里就是这样做的。

查找
遍历文件,并向每个
cat
调用的命令行添加尽可能多的文件:

find . -type f -name '*.txt' -exec cat '{}' + >all.txt
如果您的
查找
不支持
-exec。。。{}+
(如果符合当前版本的POSIX规范,它应该这样做),还有一种使用GNU扩展使xargs安全的方法:

find . -type f -name '*.txt' -print0 | xargs -0 cat >all.txt
在没有
-0
的情况下使用xargs是不安全的——在这种情况下,它不能正确处理带有换行符的文件名,以及其他问题(其中一些问题可以通过其他选项避免,但并非所有问题)。想想看,一个恶意用户创建了一个文件
$'foo\n/etc/passwd'
——您不想冒着将
/etc/passwd
注入输出的风险

最后,使用
find-exec
(为找到的每个文件调用一个单独的
cat
副本)的方法效率较低,也较旧:

…或者,在类似的情况下(多次调用
cat
),您只需在shell脚本中使用一个循环:

for f in my_dir/*/*/*.txt; do
  cat "$f"
done >all.txt
请注意,这会在整个循环上执行重定向,而不是(效率较低)在每个文件的基础上执行重定向



旁白:如果使用POSIX sh或bash,则不需要引用
{}
。但是,如果试图支持
zsh
,您确实需要引用
{}
,因此我在这里这样做。

因为GNU find已经支持
-exec+,使用GNU扩展来解决缺少GNU扩展的问题,它很少会