【问题标题】:How do I replace the values in one file with the values in another file?如何将一个文件中的值替换为另一个文件中的值?
【发布时间】:2018-11-01 00:37:12
【问题描述】:

我有 2 个制表符分隔的文件,如下所示:

file1.txt

chr1    710000  715000  143
chr1    715000  720000  144
chr1    720000  725000  145
chr1    725000  730000  146
chr1    730000  735000  147
chr1    735000  740000  148
chr1    740000  745000  149
chr1    745000  750000  150
chr1    750000  755000  151
chr1    755000  760000  152
chr1    760000  765000  153

file2.txt

143 143 84
143 144 26
143 152 32
143 153 15
144 152 11

预期输出:

output.txt

chr1    710000  715000  chr1    710000  715000  84
chr1    710000  715000  chr1    715000  720000  26
chr1    710000  715000  chr1    755000  760000  32
chr1    710000  715000  chr1    760000  765000  15
chr1    715000  720000  chr1    755000  760000  11

我想将 file1.txt(第 4 列)中的唯一数字与 file2.txt(第 1 和 2 列)中的数字进行匹配,并将它们替换为file1.txt(第 1-3 列)中的值。 output.txt 应该有 7 列,其中最后一列具有 file2.txt(第 3 列)中的相应值。

【问题讨论】:

  • 文件是否已排序/可排序?让它们匹配顺序可能会简化所需的逻辑。另外,文件有多大?

标签: python bash


【解决方案1】:

如果 file1.txt 不是很大,您可以将其加载到内存中并使用表查找。

$: cat match
#! /bin/env bash

declare -a lookup=()
while read a b c i
do lookup[$i]="$a       $b      $c" # embedded tabs here
done < file1.txt

while read a b v
do printf "%s\t%s\t$v\n" "${lookup[$a]}" "${lookup[$b]}" # use quotes!
done < file2.txt

$: bash match
chr1    710000  715000  chr1    710000  715000  84
chr1    710000  715000  chr1    715000  720000  26
chr1    710000  715000  chr1    755000  760000  32
chr1    710000  715000  chr1    760000  765000  15
chr1    715000  720000  chr1    755000  760000  11

【讨论】:

  • 如果第一个文件太大,您可能需要进行排序并行读取,这是可行的,但工作量更大。
  • 另外,如果有很多未使用的单元格,使用关联数组可能会更有效。有人对此有什么想法吗?
  • 您怀疑文件很大,感谢您的帮助和建议。看起来它正在工作,虽然真的很慢。对于那些感兴趣的人,以上文件是 HiC-Pro 管道的输出,可生成染色体内和染色体间接触图。
  • 用相同的逻辑在 Perl 中重新实现可能会更快。我们是否需要编写更快和/或更少内存滥用的版本?
  • 如果您真的受内存限制,那么它实际上可能会加快速度,以便仅在需要时将记录添加到查找中,然后在您确定会从表中删除它们时不再需要它们。继续检查然后执行添加/删除操作以支持移动窗口需要更多的工作,但是对于非常大的数据集可能会释放 大量 内存以提高性能。
【解决方案2】:

q command 可以将 sql 查询应用于表格文本文件。以下命令会产生您预期的输出。

q -t 'SELECT a.c1, a.c2, a.c3, b.c1, b.c2, b.c3, c.c3
      FROM ./file2.txt c
      JOIN ./file1.txt a ON a.c4 = c.c1
      JOIN ./file1.txt b ON b.c4 = c.c2'

它非常简洁,但对于大文件来说不是很快。但是,它可能比普通的 bash 解决方案更快。

在 Ubuntu 上,您可以安装 qapt install python-q-text-as-data

【讨论】:

    猜你喜欢
    • 2019-10-27
    • 2018-01-22
    • 2022-12-17
    • 1970-01-01
    • 1970-01-01
    • 2018-09-14
    • 1970-01-01
    • 2016-12-05
    • 2021-09-18
    相关资源
    最近更新 更多