【问题标题】:How to change a pattern in a file that match in pattern from column 1 in other file, and then print the pattern of column 2?如何更改文件中与其他文件中第 1 列的模式匹配的模式,然后打印第 2 列的模式?
【发布时间】:2019-10-03 12:04:31
【问题描述】:

我有一个文件gff3.txt 包含这种数据(数十亿行):

 scaffold1000|size145372 . gene 16987 23149 . - . ID=evm.TU.scaffold1000|size145372.2;Name=EVM%20prediction%20scaffold1000|size145372.2
 scaffold1000|size145372 . mRNA 16987 23149 . - . ID=evm.model.scaffold1000|size145372.2;Parent=evm.TU.scaffold1000|size145372.2;Name=EVM%20prediction%20scaffold1000|size145372.2
 scaffold1000|size145372 . exon 22965 23149 . - . ID=evm.model.scaffold1000|size145372.2.exon1;Parent=evm.model.scaffold1000|size145372.2
 scaffold9|size467357 . gene 373475 396789 . + . ID=evm.TU.scaffold9|size467357.56;Name=EVM%20prediction%20scaffold9|size467357.56
 scaffold9|size467357 . mRNA 373475 396789 . + . ID=evm.model.scaffold9|size467357.56;Parent=evm.TU.scaffold9|size467357.56;Name=EVM%20prediction%20scaffold9|size467357.56
 scaffold9|size467357 . exon 373475 373695 . + . ID=evm.model.scaffold9|size467357.56.exon1;Parent=evm.model.scaffold9|size467357.56
 ...

还有一个文件`position.txt(十亿行):

 scaffold1000|size145372.2  scaffold1000|size145372:16987-23149
 scaffold9|size467357.56    scaffold10008|size45161:373475-396789
 ...

我搜索得到这个:

 scaffold1000|size145372 . gene 16987 23149 . - . ID=evm.TU.scaffold1000|size145372:16987-23149;Name=EVM%20prediction%20scaffold1000|size145372:16987-23149
 scaffold1000|size145372 . mRNA 16987 23149 . - . ID=evm.model.scaffold1000|size145372:16987-23149;Parent=evm.TU.scaffold1000|size145372:16987-23149;Name=EVM%20prediction%20scaffold1000|size145372:16987-23149
 scaffold1000|size145372 . exon 22965 23149 . - . ID=evm.model.scaffold1000|size145372:16987-23149.exon1;Parent=evm.model.scaffold1000|size145372:16987-23149
 scaffold9|size467357 . gene 373475 396789 . + . ID=evm.TU.scaffold10008|size45161:373475-396789;Name=EVM%20prediction%20scaffold10008|size45161:373475-396789
 scaffold9|size467357 . mRNA 373475 396789 . + . ID=evm.model.scaffold10008|size45161:373475-396789;Parent=evm.TU.scaffold10008|size45161:373475-396789;Name=EVM%20prediction%20scaffold10008|size45161:373475-396789
 scaffold9|size467357 . exon 373475 373695 . + . ID=evm.model.scaffold10008|size45161:373475-396789.exon1;Parent=evm.model.scaffold10008|size45161:373475-396789
 ...

所以我想在gff3.txt 文件的$9 列中找到与position.txt 中的$1 列匹配的模式,然后用@987654333 的第2 列的模式更改它们@文件。

我用 awk 试过了:

 awk '
     NR==FNR{a[$9]
     next
 }
 ($2 in a) {
     print
 }' gff3.txt position.txt > output.txt

但这没有用。可能是因为gff3.txt 的列$9 中的模式包含在其他信息中?

我也尝试用我的数据调整这些线程,但我没有实现:stackoverflow1stackoverflow2stackoverflow3stackExchange...

任何关于在awksed 或其他人中编码的建议将不胜感激。

【问题讨论】:

  • position.txt 文件的大小(条目数)是多少?
  • @RomanPerekhrest 两个文件都有数十亿行(我通过编辑添加此信息)
  • 不要 ``awk` '` 只是awk '。没有反引号.. 你能准确地说出$9 的价值是多少吗?来自gff3.txt 的这些列?你想join 文件,但我看不到你在哪个字段加入它们。您只想用 scaffold1000|size145372.2 替换 scaffold1000|size145372:16987-23149 吗?文件是否按指定列排序?它们可以在点之前的第一列连接吗?
  • @Kamil Cuk 谢谢,当我写我的问题时这只是一个错误,当我尝试它时我只是 awk。我编辑了我的帖子,再次感谢。
  • 只需要一个简单的sed 's/scaffold9|size467357.56/scaffold10008|size45161:373475-396789/g' 就可以吗?

标签: bash awk sed vlookup gsub


【解决方案1】:

我想出了这个:

sed "$(<position.txt sed 's/\./\\./g' | xargs -n2 printf "s@%s@%s@g\n")" gff3.txt

首先,我将 position.txt 替换为 \. 中的每个 .,以便将其转义为 sed。然后从每一行我生成sed 替换命令s/&lt;first column&gt;/&lt;second column&gt;/g 使用xargs 和简单的printf。输出作为脚本提供给sedsed 接受gff3.txt 并在其上运行转换。如果没有“奇怪”的输入(嵌入空格、换行符、所有字符串都是唯一的等),我认为这可以处理。

测试脚本:

#!/bin/bash

cat <<EOF >gff3.txt 
scaffold1000|size145372 . gene 16987 23149 . - . ID=evm.TU.scaffold1000|size145372.2;Name=EVM%20prediction%20scaffold1000|size145372.2
scaffold1000|size145372 . mRNA 16987 23149 . - . ID=evm.model.scaffold1000|size145372.2;Parent=evm.TU.scaffold1000|size145372.2;Name=EVM%20prediction%20scaffold1000|size145372.2
scaffold1000|size145372 . exon 22965 23149 . - . ID=evm.model.scaffold1000|size145372.2.exon1;Parent=evm.model.scaffold1000|size145372.2
scaffold9|size467357 . gene 373475 396789 . + . ID=evm.TU.scaffold9|size467357.56;Name=EVM%20prediction%20scaffold9|size467357.56
scaffold9|size467357 . mRNA 373475 396789 . + . ID=evm.model.scaffold9|size467357.56;Parent=evm.TU.scaffold9|size467357.56;Name=EVM%20prediction%20scaffold9|size467357.56
scaffold9|size467357 . exon 373475 373695 . + . ID=evm.model.scaffold9|size467357.56.exon1;Parent=evm.model.scaffold9|size467357.56
EOF

cat <<EOF >position.txt
scaffold1000|size145372.2  scaffold1000|size145372:16987-23149
scaffold9|size467357.56    scaffold10008|size45161:373475-396789
EOF

cat <<EOF >exp.txt
scaffold1000|size145372 . gene 16987 23149 . - . ID=evm.TU.scaffold1000|size145372:16987-23149;Name=EVM%20prediction%20scaffold1000|size145372:16987-23149
scaffold1000|size145372 . mRNA 16987 23149 . - . ID=evm.model.scaffold1000|size145372:16987-23149;Parent=evm.TU.scaffold1000|size145372:16987-23149;Name=EVM%20prediction%20scaffold1000|size145372:16987-23149
scaffold1000|size145372 . exon 22965 23149 . - . ID=evm.model.scaffold1000|size145372:16987-23149.exon1;Parent=evm.model.scaffold1000|size145372:16987-23149
scaffold9|size467357 . gene 373475 396789 . + . ID=evm.TU.scaffold10008|size45161:373475-396789;Name=EVM%20prediction%20scaffold10008|size45161:373475-396789
scaffold9|size467357 . mRNA 373475 396789 . + . ID=evm.model.scaffold10008|size45161:373475-396789;Parent=evm.TU.scaffold10008|size45161:373475-396789;Name=EVM%20prediction%20scaffold10008|size45161:373475-396789
scaffold9|size467357 . exon 373475 373695 . + . ID=evm.model.scaffold10008|size45161:373475-396789.exon1;Parent=evm.model.scaffold10008|size45161:373475-396789
EOF

sed "$(<position.txt sed 's/\./\\./g' | xargs -n2 printf "s@%s@%s@g\n")" gff3.txt > output.txt

diff exp.txt output.txt

diff 不打印任何内容,因此它适用于指定的示例输入和预期输出。

【讨论】:

  • “十亿行”因素将成为这种方法可行性的关键测试标准
【解决方案2】:

找到了这个解决方案,我有点喜欢它,但请务必先复制您的文件,因为它会替换上面的内容,如果它不能按预期工作,您可能会丢失信息。

GNU sed:

sed 's, +,$ ,g' position.txt | xargs -I {} sed -i 's {} g' gff3.txt

MAC 操作系统:

sed -E 's, +,$ ,' position.txt | xargs -I {} sed -i '' 's {} g' gff3.txt

xargs -I 将为 gff3.txt 上的 position.txt 的每一行执行 sed

{} 将替换为 gff3.txt 的行。第一列用作模式,第二列用作新值。

【讨论】:

  • 这将如何进行适当的替换?
  • @RomanPerekhrest 你试过这个解决方案吗?我得到了确切的预期结果。
  • @RomanPerekhrest 您尝试过 GNU sed 解决方案吗?看起来您的 sed 不喜欢 -i 选项后的 ''
  • 我认为我修复了 GNU 解决方案。问题是 position.txt 有多个空格,而 GNU sed 不喜欢这样。感谢您的帮助。
  • 如果 MacOS 解决方案伪装成替代方案,请对其进行适当的更正
猜你喜欢
  • 2013-04-03
  • 2013-09-17
  • 2015-08-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多