使用linux查找并替换制表符分隔文件中的列中的值

时间:2016-10-04 17:45:40

标签: linux perl awk bioinformatics

我在下面有这些数据,例如:

Name  Chrom  Position
rs1    1     1234  
rs2    1     1789   
rs3    1     1289   
1      1     1269   
2      1     1897

我想找到第一列中不包含字符串“rs”的所有行,并替换为rs'chrom''position'。名称1看起来像rs11269

最终看起来像这样:

Name  Chrom  Position   
rs1     1     1234  
rs2     1     1789   
rs3     1     1289   
rs11269 1     1269   
rs11897 1     1897

我知道awk我可以做到

awk '!/rs/{print $1}' file

并且它会在第一列中找到不包含字符串“rs”的所有行,但是现在如何进一步将其替换为我自己的从chrom和position构建的rs ID?我会使用gsub还是别的什么?这不一定是在shell命令中,而且Perl也是另一个使用的选项。谢谢您的帮助。

2 个答案:

答案 0 :(得分:1)

您可以使用此命令:

$ awk 'BEGIN{FS=OFS="\t"}NR>1&&!($1~/rs/){$1="rs"$2$3}1' file
Name     Chrom  Position
rs1      1      1234
rs2      1      1789
rs3      1      1289
rs11269  1      1269
rs11897  1      1897

使用BEGIN{FS=OFS="\t"}我们将输入和输出字段分隔符设置为制表符,NR>1&&!($1~/rs/)我们过滤不是第一个(标题)且不包含字符串的行#34 ; RS"在第一个字段中,使用{$1="rs"$2$3}我们将第一个字段的值更改为所需的值。最终1是真实条件,因此所有行都被打印出来。

答案 1 :(得分:0)

perl中的解决方案:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<强>输出:

#!/usr/bin/perl 

use strict; 
use warnings; 

use Data::Dumper;

my $row;

#   Open file to read.
open (my $FH, '<', 'test') or die ($!);

# Write new updated file.
open (my $OUT, '>', 'updated_test') or die ($!);


while (my $line = <$FH>){
    chomp($line);
    my @val = split( "\t" , $line );

    if ( $val[0] !~  m/rs/ ) { 
        my $row = "rs" . $val[0] . $val[1] . $val[2] . "\t" . $val[1] . "\t" . $val[2];
        print $OUT $row."\n";
    } 
    else{
        print $OUT $line."\n";
    }
}

close $FH;  
close $OUT;