14

我正在将一个非常巨大的文件加载到 postgresql 数据库中。为此,我首先split在文件中使用以获取较小的文件(每个 30Gb),然后使用 and 将每个较小的文件加载到数据库GNU Parallelpsql copy

问题是拆分文件大约需要 7 个小时,然后它开始为每个核心加载一个文件。我需要一种方法来告诉split每次它完成写入文件时将文件名打印到std输出,这样我就可以将它通过管道传输到Parallel它并在完成写入时开始加载文件split。像这样的东西:

split -l 50000000 2011.psv carga/2011_ | parallel ./carga_postgres.sh {}

我已阅读split手册页,但找不到任何内容。有没有办法用split或任何其他工具做到这一点?

4

2 回答 2

30

您可以让并行进行拆分:

<2011.psv parallel --pipe -N 50000000 ./carga_postgres.sh

请注意,手册页建议使用--blockover ,默认情况下,-N这仍会在记录分隔符处拆分输入,例如:\n

<2011.psv parallel --pipe --block 250M ./carga_postgres.sh

测试--pipe-N

这是一个将 100 个数字序列拆分为 5 个文件的测试:

seq 100 | parallel --pipe -N23 'cat > /tmp/parallel_test_{#}'

检查结果:

wc -l /tmp/parallel_test_[1-5]

输出:

 23 /tmp/parallel_test_1
 23 /tmp/parallel_test_2
 23 /tmp/parallel_test_3
 23 /tmp/parallel_test_4
  8 /tmp/parallel_test_5
100 total
于 2013-02-28T20:48:51.947 回答
2

如果您使用GNU split,您可以使用该--filter选项执行此操作

'--filter=command'<br> 使用此选项,不是简单地写入每个输出文件,而是通过管道写入每个输出文件的指定 shell 命令。命令应使用 $FILE 环境变量,该变量为命令的每次调用设置为不同的输出文件名。

您可以创建一个shell脚本,该脚本创建一个文件并在后台启动carga_postgres.sh

#! /bin/sh

cat >$FILE
./carga_postgres.sh $FILE &

并使用该脚本作为过滤器

split -l 50000000 --filter=./filter.sh 2011.psv
于 2013-02-28T20:49:20.390 回答