Hi,
I got long list of reference file (column one is refer to the header in input file; column 2 is info of start position in input file; column 3 is info of end position in input file;) shown as below:
read_2 10 15
read_3 5 8
read_1 4 10
.
.
.
Input file (huge file with total file size more than 1GB):
++read_1
AFSFAFHAKSJFHAKSJFHAKJSFHAFHASJKFHAS
++read_2
ASDFASJFOASUFRIEUIEWOUIEOWUIOEWUIEWFSFSJDHGJDSKHGSKDJHG
++read_3
UTWETEWTWETEWTEWTEF
.
.
Desired output:
++read_1
AFSXXXXXXXJFHAKSJFHAKJSFHAFHASJKFHAS
++read_2
ASDFASJFOXXXXXXEUIEWOUIEOWUIOEWUIEWFSFSJDHGJDSKHGSKDJHG
++read_3
UTWEXXXXWETEWTEWTEF
.
.
I would like to replace the character in input file with "X" based on the header description (colomn 1), start position to replace (column 2), end position to replace (column) in reference file.
My input file might be quite huge (>1GB)
Thanks for any advice.
awk 'NR==FNR{a["++"$1]=$2;b["++"$1]=$3}
NR>FNR&&a[RS$1]{print RS$1"\n"substr($2,1,a[RS$1]-1)gensub(/./,"X","g",substr($2,a[RS$1],b[RS$1]-a[RS$1]+1))substr($2,b[RS$1]+1)}' ref RS="++read" file
++read_1
AFSXXXXXXXJFHAKSJFHAKJSFHAFHASJKFHAS
++read_2
ASDFASJFOXXXXXXEUIEWOUIEOWUIOEWUIEWFSFSJDHGJDSKHGSKDJHG
++read_3
UTWEXXXXWETEWTEWTEF
#!/usr/bin/perl
use strict;
my %ref_h;
my (@refdata,@ar);
my ($start,$end,$format,$col);
open(RF,"<","reffile") or die "Fail-$!\n";
while (<RF>) {
chomp;
@refdata=split;
$ref_h{$refdata[0]}=[$refdata[1],$refdata[2]]
}
close(RF);
open(DF,"<","datafile") or die "Fail-$!\n";
while (<DF>){
chomp;
if (/^\+\+/) {
($col=$_)=~s/\++//g;
next unless exists $ref_h{$col} ;
print "$_\n";
$start=$ref_h{$col}[0];
$end=$ref_h{$col}[1];
next;
}
next unless $start>0;
$format="A".($start-1)." x".($end-$start+1)." A*";
@ar=unpack($format, $_);
($ar[1],$ar[2])=("X" x ($end-$start+1),$ar[1]);
print @ar,"\n";
$start=0;$end=0;
}
close(DF);
Hi yinyuemi,
I just sent a message to your mail box.
Need your advice about it.
Thanks 
Try this,
#!/usr/bin/perl
my %ref_h;
my (@refdata,@ar);
my ($start,$end,$format,$col);
open(RF,"<","reffile") or die "Fail-$!\n";
while (<RF>) {
chomp;
@refdata=split;
push (@{$refdata[0]},$refdata[1],$refdata[2]);
$ref_h{$refdata[0]}=\@{$refdata[0]}
}
close(RF);
open(DF,"<","input_file.txt") or die "Fail-$!\n";
while (<DF>){
chomp;
if (/^\>/) {
($col=$_)=~s/\>//g;
next unless exists $ref_h{$col} ;
print "$_\n";
next;
}
$index=$#{$col};
for ($k=0;$k<=$index;$k++) {
$start=$ref_h{$col}[$k];
$end=$ref_h{$col}[++$k];
$format="A".($start-1)." x".($end-$start+1)." A*";
@ar=unpack($format,$_);
($ar[1],$ar[2])=("X" x ($end-$start+1),$ar[1]);
($_="@ar")=~s/\s//g;
undef @ar;
}
print $_,"\n";
$start=0;$end=0;$index=0;
}
close(DF);
You can use below code instead of the above red lines
substr($_,($start-1),($end-$start+1))="X" x ($end-$start);
Hi pravin27,
I just sent you a message yesterday.
Need your advice.
Thanks 
---------- Post updated 03-18-11 at 02:17 AM ---------- Previous update was 03-17-11 at 04:15 AM ----------
Hi pravin27,
I just resend you the input and reference file.
Thanks.
Try this,
Your reffile column should match with input_file.txt. I have added lowercase(lc). Hope this will resolved your problem.
#!/usr/bin/perl
my %ref_h;
my (@refdata,@ar);
my ($start,$end,$format,$col);
open(RF,"<","reffile") or die "Fail-$!\n";
while (<RF>) {
chomp;
@refdata=split;
push (@{$refdata[0]},$refdata[1],$refdata[2]);
$ref_h{lc $refdata[0]}=\@{$refdata[0]}
}
close(RF);
open(DF,"<","/tmp/input_file.txt") or die "Fail-$!\n";
while (<DF>){
chomp;
if (/^\>/) {
($col=$_)=~s/\>//g;
next unless exists $ref_h{lc $col} ;
print "$_\n";
next;
}
$index=$#{$col};
for ($k=0;$k<=$index;$k++) {
$start=$ref_h{lc $col}[$k];
$end=$ref_h{lc $col}[++$k];
substr($_,($start-1),($end-$start+1))="X" x ($end-$start);
}
print $_,"\n";
$start=0;$end=0;$index=0;
}
close(DF);