使用GNU并行拆分

时间:2013-02-28 20:05:31

标签: bash split gnu-parallel

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

问题是分割文件大约需要7个小时,然后开始为每个核心加载一个文件。我需要的是一种告诉split每次完成文件写入时将文件名打印到std输出的方法,这样我就可以将它传递给Parallel并开始加载文件split 1}}完成它的写作。像这样:

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

我已阅读split手册页,但找不到任何内容。有没有办法用split或任何其他工具执行此操作?

2 个答案:

答案 0 :(得分:24)

你可以让并行执行拆分:

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

请注意,该联机帮助页建议使用--block而不是-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

编辑:

如果分割文件太多,请使用ls -v按数字顺序对输出进行排序。

# to list files
ls -v1 /tmp/parallel_test*
# to merge
cat $(ls -v1 /tmp/parallel_test*) > merged.txt

答案 1 :(得分:2)

如果您使用GNU split,则可以使用--filter选项

执行此操作
  

“ - 滤波器=命令”
      使用此选项,而不是简单地写入每个输出文件,通过管道写入每个输出文件的指定shell命令。命令应该使用$ FILE环境变量,该变量在每次调用命令时设置为不同的输出文件名。

你可以创建一个shell脚本,它创建一个文件并在后台的末尾启动carga_postgres.sh

#! /bin/sh

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

并将该脚本用作过滤器

split -l 50000000 --filter=./filter.sh 2011.psv