【问题标题】:How to merge alternate lines to each following column?如何将交替行合并到每个以下列?
【发布时间】:2017-10-16 18:21:51
【问题描述】:

我正在尝试合并关于每一列的备用行

输入:

ind1 T G T
     T T T 
ind2 G G T 
     G T T

期望的输出:

ind1 TT GT TT
ind2 GG GT TT

我尝试了这些命令:

sed 'N;s/\n/ /' <input> output 

paste - - <input> output

但它只合并交替行但添加整行,不考虑列;例如:

ind1 T G T T T T

ind2 G G T G T T

有任何使用 bash 或 python 的想法吗?

【问题讨论】:

  • 这是一个有代表性的例子,还是仅仅是一个插图?特别是,在您的实际输入中,列数是否固定?数据是否始终是单个字母TG?领导总是ind 后跟一个数字吗?这些是制表符还是空格?
  • 是一个有代表性的例子。列中的数字是固定的;数据总是用单个字母(但不仅是 T 或 G)。前导可以是任何字符串,不一定后跟字母数。分隔符是制表符。

标签: bash awk sed merge newline


【解决方案1】:

awk 来救援!

$ awk 'NR%2 {n=split($0,a); next} 
            {for(i=1;i<n;i++) $i=a[i+1] $i; 
             print a[1],$0}' file

ind1 TT GT TT
ind2 GG GT TT

说明将奇数行拆分为列。与下一行合并并打印。偶数行少一个字段,移动并相应打印。

【讨论】:

  • 完美!这正是我一直在寻找的,令人难以置信的是 awk 在任何情况下的多功能性哈哈哈
【解决方案2】:

非 awk 解决方案,因为您在 bash 或 python 中要求答案:

cut -f 1-4 -d ' ' in   | # the delimiter is a tab here
  sed 's/^/>/'         | # replace the start of the line with a >
    while read a b c d   # read the fields
    do if [[ "$a" = '>' ]]                     # if > then a second line
       then printf "$A\t$B$b\t$C$c\t$D$d\t\n"  # so stack them
       else A=${a#'>'}; B=$b; C=$c; D=$d;      # else set for stack later
       fi
    done

如果您想快速处理大量数据,我会使用 perl。 或者python。

或者 C。我讨厌 awk。不敲它的能力——我只是不喜欢它。

【讨论】:

  • 感谢 Paul Hodges,但问题是它有超过 150000 个字段,因此无需设置要读取的字段 a-d 就更容易了。非常感谢您的解释,我可能会将它用于较小的文件。
  • 然后我肯定使用 Perl 并在带有警告、严格和大量 cmets 的 repo 中编写代码。 Perl 在生物信息学方面有相当多的历史。
【解决方案3】:

GNU awk 解决方案(针对您当前的输入):

awk -F'\t' -v FPAT='[^[:space:]]+' 'NF>3{ h=$1; for(i=1;i<=3;i++) a[i]=$(i+1) }
              NF==3{ print h,a[1]$1,a[2]$2,a[3]$3 }' OFS='\t' file

输出:

ind1    TT  GT  TT
ind2    GG  GT  TT

【讨论】:

    猜你喜欢
    • 2021-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-14
    • 2021-07-16
    • 1970-01-01
    • 1970-01-01
    • 2014-11-08
    相关资源
    最近更新 更多