Hello,
Could you please help me in following scenario in Perl scripting?
I want to compare two text files & change the charter at the position. Output of this comparision in third file with flags C-CHANGE, N-SAME at the end of line.

IN PUT1: 
    Posi      
      3    ATG   
      2    ACT
      1    ATC
      ........
      IN PUT2:
     ref  Multant 
      G    C 
      C    A
      A    A
      ........
OUT PUT:
    posi  Ref  Mul
      3   ATG  ATC  CHANGE
      2   ACT  AAT  CHANGE
      1   ATC  ATC  SAME
      .................

Dani AI

Generated

Clarification and practical approach (short): the goal is to take a codon/triplet from file A and, for a given position within that triplet, change the nucleotide according to file B and label the result as CHANGE or SAME. Note: ATG is a codon (three nucleotides), not an amino acid. Treat positions as 1-based (leftmost base = position 1) unless your data says otherwise. showed the basic line-by-line idea that works for small datasets; ’s scaling concern and ’s question about what to do when the reference does not match are both important—you should validate and decide whether to enforce the reference or force the change.

Recommended minimal algorithm

  1. Stream both files in parallel (do not slurp giant files).
  2. For each pair of lines: parse position, codon, ref, alt; trim whitespace and ignore blanks/comments.
  3. Validate position is inside the codon length. If the codon char at that position differs from ref, either (a) report/refuse (safe) or (b) still apply alt but flag a REF_MISMATCH (explicit).
  4. Write output: position, original codon, mutated codon, and one of SAME, CHANGE, REF_MISMATCH.

Example helper (Perl) — compact, different from earlier post:

sub apply_mutation {
    my ($codon, $pos, $ref, $alt, $force) = @_;
    my @b = split //, $codon;
    my $i = $pos - 1;
    return ($codon, "INVALID_POS") if $i < 0 || $i > $#b;
    my $orig = $b[$i];
    if ($orig ne $ref && !$force) { return ($codon, "REF_MISMATCH:$orig"); }
    $b[$i] = $alt;
    return (join("", @b), $orig eq $alt ? "SAME" : "CHANGE");
}

Call this for each paired line and print a tab-separated row.

Practical tips: normalize whitespace, handle unequal line counts explicitly, offer a command-line flag to force non-matching replacements, and validate a sample before processing millions of rows. For many mutations per sequence, group changes by sequence ID (load indexed sequences) rather than line-by-line.

Recommended Answers

All 7 Replies

Looks to me liek you are trying to compare DNA sequences.. in that case will it be correct to assume that the character sets will all be of length 3? Also i suspect these files would run into millions of rows then?

Looks to me liek you are trying to compare DNA sequences.. in that case will it be correct to assume that the character sets will all be of length 3? Also i suspect these files would run into millions of rows then?

you right! I am try to compare DNA sequence. I know the positions where sequence and what kind Nuleotid were changed. I used excel to change chacter of sequence but I hope I can do it with Perl. Could you show me to do it?

I'm trying, but I can't figure out how your output follows from your input. Can you explain the problem more clearly?

I'm trying, but I can't figure out how your output follows from your input. Can you explain the problem more clearly?

I can do it with excel by Replace comand. I hope I can do it with perl. For ex amino acid ATG was changed at position 3 of that amino acid and the charter was changed G by C. Out put: at postion 3 of ATG was changed --> ATC and label "Change". I hope it helps you understand my problem.

Ok, wait.

If your first file says what position you want to change, why does your second file say what character you want to change? If the "reference" character in file 2 is different from the character found at the position given in file 1, do you still change it to the "mutant" (not "multant") form?

I might also ask, how do you do it in Excel?

input1.csv

3    ATG   
2    ACT
1    ATC

input2.csv

G    C 
C    A
A    A
#!/usr/bin/perl;
use strict;
use warnings;

my ($filename1, $filename2) = ('input1.csv', 'input2.csv');

open my $fh1, '<', $filename1 or die "Failed to open $filename1: $!";
open my $fh2, '<', $filename2 or die "Failed to open $filename2: $!";

while (my $rec1 = <$fh1>){
    defined (my $rec2 = <$fh2>) or last;
    print compare($rec1, $rec2), "\n";
}

sub compare{
    my ($str1, $str2) = @_;
    my ($pos, $triplet) = split(/\s+/, $str1);
    my ($ref, $mut) = split(/\s+/, $str2);
    my $idx = $pos - 1;#index starts at 0
    my $origtriplet = $triplet;
    my $origchar = substr($triplet, $idx, 1);
    my $stat;
    
    if ($origchar eq $ref){
        substr($triplet, $idx, 1) = $mut;
    }
    
    if ($origchar eq $mut){
        $stat = 'SAME';
    }
    else {
        $stat = 'CHANGE';
    }
    
    return "$origtriplet\t$triplet\t$stat";
}

Outputs

ATG	ATC	CHANGE
ACT	AAT	CHANGE
ATC	ATC	SAME

Thank you very much for your tutoral.
It is so good for me.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.