Bash:使用cat来处理很多文件时遇到麻烦

时间:2013-12-07 15:38:09

标签: bash limit command-line-arguments cat

对于每组参数,我尝试将400个数据文件合并为13行,每个数据文件大一个,如下所示:

folders=(*/)
for folder in ${folders[@]}; do
    #FIND SIGMA
    sig0=${folder#*sig}
    sig=${sig0%amax*}
    #MERGE
    cat sig${sig}amax0.6_incr0.1/tau*.dat > merged_sigma${sig}amax0.6_incr0.1.dat
done

合成文件应该有5200行很简单,但它没有 相反,每个合并文件具有不同数量的行,在大约3100和5000之间变化。

我检查过所有tau*.dat个文件都存在,不是空的,只有13行。 在小文件的末尾缺少换行符没有问题。在合并文件中,所有行都具有相同的长度。只是一些 - 而且在我看来是以随机方式 - 缺失了。

我在某处读到所有文件名中的字符总数不得超过32767个字符。但是,即使考虑到文件名不是tau*.dat而是sig0.10amax0.1_incr0.1/tau27.0_sigma0.10__-0.6-0.6_0-0_0.1.dat,每个cat命令只有不超过25000个字符。

2 个答案:

答案 0 :(得分:0)

我会做什么:

folders=(*/)
for folder in ${folders[@]}; do
    #FIND SIGMA
    sig0=${folder#*sig}
    sig=${sig0%amax*}
    #MERGE
    for file in sig${sig}amax0.1_incr0.1/tau*.dat; do
        cat "$file" >> "merged_sigma${sig}amax0.6_incr0.1.dat"
    done
done

答案 1 :(得分:0)

注意:这个答案解释了如何避免使用globbing时命令行变得太长的问题;但是,命令行长度限制出现而不是是OP问题的根源。

要可靠地处理扩展到任意大小的参数列表的球体 - 而不必担心遇到命令行长度限制 - 您可以使用以下方法:

printf '%s\0' *  | xargs -0 ...

这基于以下假设

  • printf(也是) shell内置,因此受命令行长度限制(由getconf ARG_MAX报告 - 环境的大小;请参阅http://www.in-ulm.de/~mascheck/various/argmax/) - 至少对于bash是真的(运行type printf以验证您的shell中printf是内置的)。
  • xargs支持-0选项接受null char.-separated输入;请注意,xargs的核心功能是遵守命令行长度限制,并在必要时将参数列表分区为指定命令的多个调用
    • 警告-0是一个非标准(不符合POSIX)选项,但它在Linux和类似BSD的平台(如OSX)上都受支持。
  • (只有当您知道您的文件名不包含空格(且没有换行符)并且不以-开头时,您才能使用简化形式echo * | xargs ...,同样假设echo是一个内置的shell。)

如果我们将这种方法应用于OP的代码,我们得到:

printf '%s\0' sig${sig}amax0.6_incr0.1/tau*.dat | 
  xargs -0 cat > merged_sigma${sig}amax0.6_incr0.1.dat