theo4786 theo4786 - 3 months ago 14
Perl Question

perl one liner to add column to file if second field matches

I have a file that for some rows has 4 fields and for some rows has 3 fields, and looks like:

1 rs17125090 63988904 ENSG00000142856
7 7.87455705 ENSG00000075303


In the cases where the row has 3 fields, the second field matches "number.longer number" whereas if the row has 4 fields, the second field matches "rsnumber". In the instances where the row has 3 fields, I would like to add a field in the third column that contains a number equal to the second field, split by ".". For example, the resulting file would look like:

1 rs17125090 63988904 ENSG00000142856
7 7.87455705 87455705 ENSG00000075303


My perl one liner is:

perl -e 'for(`cat file`){my@L=split;if($L[1]=~m/^\d+\.\d+$/){my@snp=split(/\./,$L[1]);splice(@L,2,0,$snp[1])}}open OUT,">file.new";print OUT "@L\n"; close OUT'


But I just get an empty file. Can someone fix this/let me know what's going wrong?

Answer

You need to be very careful when writing one-line programs. Many of the normal safeguards are not in place, and it is far less easy to spot an error when ther is no layout

Your code is equivalent to this program

for ( `cat file` ) {

    my @L = split;

    if ( $L[1] =~ m/^\d+\.\d+$/ ) {
        my @snp = split( /\./, $L[1] );
        splice( @L, 2, 0, $snp[1] );
    }
}

open OUT, ">file.new";
print OUT "@L\n";
close OUT;

Can you see now where the problem lies?

This should do what you need

perl -anE 'splice @F, 2, 0, $F[1] =~ /\.(\d+)/; say "@F";' myfile