【问题标题】:Reorder text file lines by a specific scheme with bash or awk使用 bash 或 awk 按特定方案重新排序文本文件行
【发布时间】:2018-07-25 02:22:09
【问题描述】:

我需要弄清楚如何在 bash 中重新排序一个文本文件,该文件是由另一个脚本制作的,由许多具有特定方案的行组成。这是其中的 12 个。

>NODE_3
nucleotide_cov: 170.3683
GC_CONT: 37.00
>NODE_18
nucleotide_cov: 168.8670
GC_CONT: 37.00
>NODE_23
nucleotide_cov: 178.0648
GC_CONT: 35.00
>NODE_41
nucleotide_cov: 174.4054
GC_CONT: 36.00

需要的输出是:

GC_CONT: 37.00  nucleotide_cov: 170.3683    >NODE_3
GC_CONT: 37.00  nucleotide_cov: 168.8670    >NODE_18
GC_CONT: 35.00  nucleotide_cov: 178.0648    >NODE_23
GC_CONT: 36.00  nucleotide_cov: 174.4054    >NODE_41

每一列都被制表符分割,所以“\t”和GC_CONT需要是它们的第一个值。 首选 awk 解决方案。

编辑

我会尽量说清楚。这是使用

的输出文件
awk 'NR%3{printf "%s ",$0;next;}1' input.txt 

>NODE_3 nucleotide_cov: 170.3683 GC_CONT: 37.00
>NODE_18 nucleotide_cov: 168.8670 GC_CONT: 37.00
>NODE_23 nucleotide_cov: 178.0648 GC_CONT: 35.00
>NODE_41 nucleotide_cov: 174.4054 GC_CONT: 36.00

很好,但我需要格式化它们以便在每一行的开头都有“GC_CONT:”。

【问题讨论】:

  • 我不明白你的意思是“每列都由制表符分隔,所以“\t”和 GC_CONT 必须是它们的第一个值。”
  • @PierreFrançois 查看问题更新

标签: bash awk sed grep sh


【解决方案1】:

选择你喜欢的:

简单的awk单行:

awk '/^>/{ n=NR; r=$0; next }{ r=$0 OFS r; if (NR-n==2) print r }' OFS='\t' input.txt

awk解决严格的行序:

awk '/^>/{ r1=$0; n=NR }
     n{ if (NR == n+1) r2=$0; else if (NR == n+2) print $0, r2, r1 }' OFS='\t' input.txt

输出:

GC_CONT: 37.00  nucleotide_cov: 170.3683    >NODE_3
GC_CONT: 37.00  nucleotide_cov: 168.8670    >NODE_18
GC_CONT: 35.00  nucleotide_cov: 178.0648    >NODE_23
GC_CONT: 36.00  nucleotide_cov: 174.4054    >NODE_41

【讨论】:

  • 正常工作。谢谢!您能否解释一下,在代码中,每一行如何被标识为“line 1”、“line 2”和“line 3”?因为最后一部分,即印刷部分,流畅且易于理解。
  • @Shred,欢迎。 print $0, r2, r1 表示:打印当前记录$0(即第3行),第二行r2和第一行r1。另外,检查我的单线
【解决方案2】:

试试这个 awk 脚本:

/^>/    {node=$0}
/^nucl/ {nucl=$0}
/^GC/   {print $0 "\t" nucl "\t" node}

或者,从命令行:

awk '/^>/{node=$0} /^nucl/{nucl=$0} /^GC/{print $0 "\t" nucl "\t" node}' input_file

【讨论】:

  • 我也是,但@RomanPerekhrest 的回答更快更详细,因为他还提供了输出样本,这意味着他真的了解我在寻找什么。你的那个更干净,更容易理解,谢谢。
  • @Shred:好的,没问题,但如果您将接受的解决方案授予 RomanPerekhrest,也将不胜感激。
  • @Shred:没问题。谢谢。
【解决方案3】:

仅供参考,标记为sed

sed -r '/^>/{N;N;s/(.*)\n(.*)\n(.*)/\3\t\2\t\1/g}'

【讨论】:

  • Sed 在计算方面是一个非常糟糕的解决方案。
  • 那你为什么要标记?
【解决方案4】:

这可能对你有用(GNU sed):

sed -r ':a;N;/\n>/!s/(.*)\n(.*)/\2\t\1/;ta;P;D' file

收集记录所需的行,交换行并用制表符替换换行符。

【讨论】:

  • 如下所述,这里的 sed 解决方案很糟糕。
猜你喜欢
  • 2020-10-31
  • 2012-09-17
  • 2020-12-28
  • 1970-01-01
  • 1970-01-01
  • 2018-08-25
  • 2022-10-24
  • 2013-06-20
  • 1970-01-01
相关资源
最近更新 更多