根据列的数字内容从制表符分隔文件中删除列?

时间:2018-03-12 10:21:26

标签: python bash perl csv

我有一个制表符分隔文件,见下文: 第一列包含位置编号,1-end 其余的都有一些频率数字。

Position     A    B    C    D
1          117    0    1    0   
2            4    0    0   16   
3            0    5   11    0   
4            0    0    0    5   
5            0   15    0    0   
6          100    0  108    0   
7            0    0  147    0  

我想将此文件重新格式化为两列,第一列是保持原样的位置列,第二列是每个位置的最高频率。

理想输出:

Position    HighFreq
1                117
2                 16  
3                 11  
4                  5   
5                 15   
6                108  
7                147 
到目前为止我所拥有的是一个选择最高数字并打印的函数:

awk '{max=$1; for(i=2;i<=NF; i++) {if($i>max){max=$i;}};printf"%f\n",max}' file.tsv

我正在尝试为这个问题编写一个bash解决方案,但是非常欢迎Perl / Python!

4 个答案:

答案 0 :(得分:3)

$ perl -MList::Util=max -F/\t/ -lane 'print join "\t", $. == 1 ? qw(Position HighFreq) : ( $F [0], max(@F[1..$#F]) )'

<强>解释

  • <强> -MList::Util=max

    加载List::Util::max

  • <强> -F/\t/ -a

    激活自动拆分并将分隔符设置为/\t/

  • <强> -lne

    自动附加相应的行结尾,应用单行,逐行处理ARGV

  • <强> print join "\t", ...

    打印标签分隔

  • <强> $. == 1 ? ... : ...

    处理栏目标题

  • <强> max( @F[1..$#F] )

    返回@F

  • 的所有首要元素的最大值

答案 1 :(得分:0)

当你选择了Python标签时,可以在Python中完成,如下所示:

import sys
import csv

with open(sys.argv[1], 'rb') as f_input:
    tsv = csv.reader(f_input, delimiter='\t')
    next(tsv)
    data = []

    for row in tsv:
        row = map(int, row)
        data.append([row[0]] + [max(row[1:])])

with open(sys.argv[1], 'wb') as f_output:
    tsv = csv.writer(f_output, delimiter='\t')
    tsv.writerow(['Position', 'HighFreq'])
    tsv.writerows(data)

答案 2 :(得分:0)

awk 'BEGIN{print"Position\tHighFreq"}{if(NR==1)next; max=0;for(i=2;i<=NF; i++) {if($i>max){max=$i;}} printf"%d\t%d\n",$1,max;}' file.tsv

输出:

Position    HighFreq
1   117
2   16
3   11
4   5
5   15
6   108
7   147

答案 3 :(得分:0)

在Perl中

use strict;
use warnings 'all';
use feature 'say';
use autodie;

use List::Util 'max';

open my $fh, '<', 'freq.txt';

<$fh>;
say join "\t", qw/ Position HighFreq /;

while ( <$fh> ) {
    my ($n, @fields) = split;
    say join "\t", $n, max(@fields);
}

输出

Position    HighFreq
1   117
2   16
3   11
4   5
5   15
6   108
7   147