我正在运行一个 awk 脚本,我想通过 GNU 并行对其进行并行化。
该脚本根据每一行上的值将一个输入文件多路分解为多个输出文件。代码如下:
#!/usr/bin/awk -f
BEGIN{ FS=OFS="\t" }
{
# bc is the field that defines to which file the line
# will be written
bc = $1
# append line to such file
print >> (bc".txt")
}
我想通过以下方式使用 GNU 并行对其进行并行化:
parallel --line-buffer --block 1G --pipe 'awk script.awk'
但是,我担心两个 awk 进程同时写入同一个文件时可能出现的竞争情况。是否可能,如果可能,如何在不影响并行性的情况下避免这种情况?
注意。包括我--line-buffer
选项,尽管我不确定它是否也适用于 awk 脚本内的文件重定向。它是否也适用于这种情况或仅适用于每个 awk 进程的标准输出?
Example
# Input file
bc1 line1
bc3 line2
bc1 line3
bc2 line4
# Output file bc1.txt
bc1 line1
bc1 line3
# Output file bc2.txt
bc2 line4
# Output file bc3.txt
bc3 line2
您可以通过对不同目录中的输出进行多路分解来实现:
stuff |
parallel --block 10M --pipe --round-robin \
'mkdir -p dir-{%}; cd dir-{%}; awk ../script.awk'
或者如果输入是文件,您可以使用--pipepart
哪个更快:
parallel --block -1 --pipepart -a bigfile \
'mkdir -p dir-{%}; cd dir-{%}; awk ../script.awk'
那么就没有竞争条件了。通过合并目录完成:
parallel 'cd {}; ls' ::: dir-* | sort -u |
parallel 'cat */{} > {}'
如果无法接受合并(也许您没有磁盘空间来容纳 2 个数据副本),则可以使用 fifo。但要做到这一点,你需要知道所有的名字.txt
- 提前创建文件,并且您需要一个可以并行运行每个名称一个进程的系统(10000 个名称 = 10000 个进程):
# Generate names-of-files.txt somehow
# Make fifos for all names in all slots
parallel 'mkdir -p {2}; mkfifo {2}/{1}' :::: \
names-of-files.txt <(seq $(parallel --number-of-threads) )
# Run the demultiplexer in the background
parallel --block -1 --pipepart -a bigfile \
'mkdir -p dir-{%}; cd dir-{%}; awk ../script.awk' &
# Start one process per name
# If you have more than 32000 names, you will need to increase the number
# of processes on your system.
cat names-of-files.txt |
parallel -j0 --pipe -N250 -I ,, parallel -j0 'parcat */{} > {}'
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)