Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/grails/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash 使用GNU与Split并行_Bash_Split_Gnu Parallel - Fatal编程技术网

Bash 使用GNU与Split并行

Bash 使用GNU与Split并行,bash,split,gnu-parallel,Bash,Split,Gnu Parallel,我正在将一个相当大的文件加载到postgresql数据库中。为此,我首先在文件中使用split来获得较小的文件(每个30Gb),然后使用GNU Parallel和psql copy将每个较小的文件加载到数据库中 问题是分割文件大约需要7个小时,然后开始为每个核心加载一个文件。我需要的是一种方法,告诉split在每次完成文件写入时将文件名打印到std输出,这样我就可以通过管道将其传输到Parallel,并在split完成写入时开始加载文件。大概是这样的: split -l 50000000 201

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

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

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

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

您可以让parallel执行拆分:

<2011.psv parallel --pipe -N 50000000 ./carga_postgres.sh
测试
--管道
-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
如果使用,可以使用
--filter
选项执行此操作

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

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

#! /bin/sh

cat >$FILE
./carga_postgres.sh $FILE &
并使用该脚本作为过滤器

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

split--verbose maybe?@KevinDTimm verbose选项在开始创建文件时打印,而不是在完成时打印,因此,在创建文件X2时,开始解析文件X1:)@KevinDTimm,但我想避免需要额外的脚本来执行此操作。parallel的
--pipe-N 50000000
选项将50000000行发送到
carga_postgres.sh
stdin?@Topo:是的。我对答案进行了编辑,以说明
--pipe
-N
的工作原理。由于您的输入量巨大,您可能需要查看--joblog--resume--resume failed(需要版本20130222)。@Thor我非常喜欢您的答案,但当我运行它时,zsh给了我一个错误,类似于:
zsh:4预期的数字
,我只能找出问题所在。@Topo:我也使用了
zsh
,但无法重现此错误。这个测试示例有效吗?您使用的是什么版本的
parallel
zsh
?如果您在
zsh-f
下运行此程序是否有帮助?在您的示例中,
cat
所做的是将
split
通过stdin发送的每一行写入文件
$file
,然后将
$file
文件名传递给carga_postgres?@Topo Correct,split将这些行发送到过滤器的stdin
$FILE
是split选择的名称。当然,您可以自由使用另一个唯一的名称。我已经做了一些小测试(只需在每个文件中执行
head-1
),当我将
添加到过滤器标志的末尾时,为
拆分生成的文件是空的,
head
命令不显示任何内容。。。但是如果我在没有
的情况下执行
split`split,则分割生成的文件是正常的,
head
会打印到屏幕上。。。这是正确的行为还是我做了一个糟糕的解释?@Topo我刚刚测试了这一点,如果您使用
&
运行筛选器,则stdin确实从
/dev/null
重定向。但是,如果在不使用的情况下运行筛选器,则split将等待筛选器退出,然后再启动下一个筛选器。因此,似乎必须使用脚本版本才能并行运行carga_postgres.sh。我相应地更新了我的答案。
split -l 50000000 --filter=./filter.sh 2011.psv