在 bash/awk/c 中粘贴数百个具有特定模式名称的文件

Paste hundreds of file with specific pattern name in bash/awk/c

我有 500 个文件,我想通过添加列来合并它们。 我的第一个文件

3
4
1
5

我的第二个文件

7
1
4
2

输出应该类似于

3 7
4 1 
1 4
5 2

但是我有500个文件(sum_1.txt,sum_501.txt直到sum_249501.txt),所以我必须有500列,所以写500个文件名会很郁闷。 有没有可能更容易做到这一点?我试试这个,但它不是 500 列,而是很多行

#!/bin/bash
file_name="sum"
tmp=$(mktemp) || exit 1 
touch ${file_name}_calosc.txt
for first in {1..249501..500}
do
paste -d ${file_name}_calosc.txt ${file_name}_$first.txt >> ${file_name}_calosc.txt
done

您的命令要求将两个文件粘贴在一起;要粘贴更多文件,请将更多文件作为 paste.

的参数

您可以像这样将多个文件粘贴在一起

paste sum_{1..249501..500}_calosc.txt > sum_calosc.txt

但是如果文件数量对于 paste 来说太大,或者生成的命令行太长,您可能仍然需要求助于临时文件。

这里尝试一次粘贴 25 个文件,然后将生成的 20 个文件合并成一个最终的大 paste

#!/bin/bash

d=$(mktemp -d -t pastemanyXXXXXXXXXXX) || exit

# Clean up when done
trap 'rm -rf "$d"; exit' ERR EXIT

for ((i=1; i<= 249501; i+=500*25)); do
    printf -v dest "paste%06i.txt" "$i"
    for ((j=1, k=i; j<=500; j++, k++)); do
        printf "sum_%i.txt\n" "$k"
    done |
    xargs paste >"$d/$dest"
done

paste "$d"/* >sum_calosc.txt

xargs 的功能是将它的输入组合成一个命令行(或者多个命令行,否则会太长;但我们在这里特别要避免这种情况,因为我们想准确控制我们传递给 paste) 的文件数量。

不管你有多少文件,这样的东西(未经测试)都应该有效:

awk '
    BEGIN {
        for (i=1; i<=249501; i+=500) {
            ARGV[ARGC++] = "sum_" i
        }
    }
    { vals[FNR] = (NR==FNR ? "" : vals[FNR] OFS) [=10=] }
    END {
        for (i=1; i<=FNR; i++) {
            print vals[i]
        }
    }
'

只有当所有文件的总内容太大而无法放入内存时才会失败。