Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/358.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/26.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
Python 处理多个文件时的快速I/O_Python_Linux_Bash_Performance_Io - Fatal编程技术网

Python 处理多个文件时的快速I/O

Python 处理多个文件时的快速I/O,python,linux,bash,performance,io,Python,Linux,Bash,Performance,Io,我有两个输入文件,我想混合它们并将结果输出到第三个文件中。在下面,我将使用一个玩具示例来解释文件的格式和所需的输出。每个文件都包含重复的4行模式(但包含不同的序列),我只包含单个4行: 输入文件1: @readheader1 ACACACACACACACACACACACACACACACACACACACACACACACACACACAC + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ... 输入文件2: @readheader2

我有两个输入文件,我想混合它们并将结果输出到第三个文件中。在下面,我将使用一个玩具示例来解释文件的格式和所需的输出。每个文件都包含重复的4行模式(但包含不同的序列),我只包含单个4行:

输入文件1:

@readheader1
ACACACACACACACACACACACACACACACACACACACACACACACACACACAC
+
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
...
输入文件2:

@readheader2
AATTAATT
+
FFFFFFFF
...
所需输出:

@readheader1_AATTAATT
ACACACACACACACACACACACACACACACACACACACACACACACACACACAC
+
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
...
因此,我想使用下划线将第一个文件中每四行的
第一行附加到第二个文件中每四行的第二行中的
小序列。我只需将第一行的每四行中的第2n行、第3行和第4行按原样输出到输出中

我正在寻找任何脚本(Linux BASH,Python,C++等),可以优化我下面的内容:

我写了这段代码来完成这项任务,但我发现速度很慢(60 GB和15 GB大小的输入需要一天以上的时间);请注意,输入文件采用
fastq.gz
格式,因此我使用gzip打开它们:

    ...
    r1_file = gzip.open(r1_file_name, 'r') # input file 1
    i1_file = gzip.open(i1_file_name, 'r') # input file 2
    
    out_file_R1 = gzip.open('_R1_barcoded.fastq.gz', 'wb') # output file

    r1_header = ''
    r1_seq = ''
    r1_orient = ''
    r1_qual = ''
    i1_seq = ''
    cnt = 1 
    with gzip.open(r1_file_name, 'r') as r1_file:
        for r1_line in r1_file:
            if cnt==1:
                r1_header = str.encode(r1_line.decode("ascii").split(" ")[0])
                next(i1_file)
            if cnt==2:
                r1_seq = r1_line
                i1_seq = next(i1_file)
            if cnt==3:
                r1_orient = r1_line
                next(i1_file)
            if cnt==4:
                r1_qual = r1_line
                next(i1_file)
                out_4line = r1_header + b'_' + i1_seq + r1_seq + r1_orient + r1_qual
                out_file_R1.write(out_4line)
                cnt = 0
            cnt += 1
    i1_file.close()
    out_file_R1.close()

    

然后,我使用2个数据集进行了两个输出,我希望交错输出文件:第一个文件的4行、第二个文件的4行、第一个文件的4行,依此类推……

使用
paste
实用程序(来自GNU coreutils)和GNU
sed

paste file1 file2 |
sed -E 'N; s/\t.*\n([^\t]*)\t(.*)/_\2\n\1/; N; N; s/\t[^\n]*//g' > file.out
如果文件是gzip文件,则使用:

paste <(gzip -dc file1.gz) <(gzip -dc file2.gz) |
sed -E 'N; s/\t.*\n([^\t]*)\t(.*)/_\2\n\1/; N; N; s/\t[^\n]*//g' > file.out
文件2:

Header2
AATTAATT
YY
GGGGGG
在执行
粘贴
命令后,行被合并,由
选项卡
s分隔:

Header1\tHeader2
ACACACACAC\tAATTAATT
XX\tYY
FFFFFFFFFFFF\tGGGGGG
上面的
\t
表示制表符。这些行被送入
sed
sed
读取第一行,模式空间变为

Header1\tHeader2
Header1\tHeader2\nACACACACAC\tAATTAATT
Header1_AATTAATT\nACACACACAC
N
命令向模式空间添加一个换行符,然后将输入的下一行(
acacac\taattatt
)追加到模式空间。模式空间变为

Header1\tHeader2
Header1\tHeader2\nACACACACAC\tAATTAATT
Header1_AATTAATT\nACACACACAC
并与regex
\t.*\n([^\t]*)\t(.*)
匹配,如下所示

Header1\tHeader2\nACACACACAC\tAATTAATT
       ||^^^^^^^||^^^^^^^^^^||^^^^^^^^
       \t   .*  \n ([^\t]*) \t  (.*)
       ||       ||    \1    ||   \2
      
\n
表示换行符。然后用
s/\t.*\n([^\t]*)\t(.*)/\u2\n\1/
命令将匹配部分替换为
\u2\n\1
。模式空间变为

Header1\tHeader2
Header1\tHeader2\nACACACACAC\tAATTAATT
Header1_AATTAATT\nACACACACAC
两个
N
命令读取下面两行。现在模式空间是

Header1_AATTAATT\nACACACACAC\nXX\tYY\nFFFFFFFFFFFF\tGGGGGG
Header1_AATTAATT\nACACACACAC\nXX\nFFFFFFFFFFFF
s/\t[^\n]*//g
命令删除选项卡(包含)和换行符(独占)之间的所有部分。完成此操作后,最终的图案空间为

Header1_AATTAATT\nACACACACAC\nXX\tYY\nFFFFFFFFFFFF\tGGGGGG
Header1_AATTAATT\nACACACACAC\nXX\nFFFFFFFFFFFF
打印为

Header1_AATTAATT
ACACACACAC
XX
FFFFFFFFFFFF

您可能希望研究使用asyncio()将代码拆分为协同路由。考虑到您的用例,它可能是最有效的工具。线程是您可以尝试的另一个选项,尽管如果您使用线程进行如此多的I/O,会浪费相当多的CPU时间。您可能还希望在处理之前解压缩文件。非常感谢;你能解释一下它是如何工作的吗?比如如何使用regex命令访问每条记录?@ameerosein补充了一个解释。