# Help with replace character based on specific location

**URL:** <https://community.unix.com/t/help-with-replace-character-based-on-specific-location/284399>\
**Category:** Shell Programming and Scripting\
**Created:** [March 11, 2011, 8:56pm UTC](https://community.unix.com/t/help-with-replace-character-based-on-specific-location/284399 "2011-03-11T20:56:36Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![perl\_beginner](https://community.unix.com/letter_avatar/perl_beginner/32/5_5575768a8748004e209b776fc1b2916d.png) [@perl\_beginner](https://community.unix.com/u/perl_beginner)\
**Post date:** [March 11, 2011, 8:56pm UTC](https://community.unix.com/t/help-with-replace-character-based-on-specific-location/284399/1 "2011-03-11T20:56:36Z")

</div>

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:

```nohighlight
read_2 10 15
read_3 5 8
read_1 4 10
.
.
.

```

Input file (huge file with total file size more than 1GB):

```nohighlight
++read_1
AFSFAFHAKSJFHAKSJFHAKJSFHAFHASJKFHAS
++read_2
ASDFASJFOASUFRIEUIEWOUIEOWUIOEWUIEWFSFSJDHGJDSKHGSKDJHG
++read_3
UTWETEWTWETEWTEWTEF
.
.

```

Desired output:

```nohighlight
++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.

---

<div class="post-metadata">

**Author:** ![yinyuemi](https://community.unix.com/letter_avatar/yinyuemi/32/5_5575768a8748004e209b776fc1b2916d.png) [@yinyuemi](https://community.unix.com/u/yinyuemi)\
**Post date:** [March 11, 2011, 9:35pm UTC](https://community.unix.com/t/help-with-replace-character-based-on-specific-location/284399/2 "2011-03-11T21:35:06Z")

</div>

```nohighlight
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

```

---

<div class="post-metadata">

**Author:** ![pravin27](https://community.unix.com/letter_avatar/pravin27/32/5_5575768a8748004e209b776fc1b2916d.png) [@pravin27](https://community.unix.com/u/pravin27)\
**Post date:** [March 12, 2011, 4:35am UTC](https://community.unix.com/t/help-with-replace-character-based-on-specific-location/284399/3 "2011-03-12T04:35:45Z")

</div>

```nohighlight
#!/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);

```

---

<div class="post-metadata">

**Author:** ![perl\_beginner](https://community.unix.com/letter_avatar/perl_beginner/32/5_5575768a8748004e209b776fc1b2916d.png) [@perl\_beginner](https://community.unix.com/u/perl_beginner)\
**Post date:** [March 14, 2011, 12:07am UTC](https://community.unix.com/t/help-with-replace-character-based-on-specific-location/284399/4 "2011-03-14T00:07:27Z")

</div>

Hi yinyuemi,

I just sent a message to your mail box.  
Need your advice about it.  
Thanks 🙂

---

<div class="post-metadata">

**Author:** ![pravin27](https://community.unix.com/letter_avatar/pravin27/32/5_5575768a8748004e209b776fc1b2916d.png) [@pravin27](https://community.unix.com/u/pravin27)\
**Post date:** [March 14, 2011, 2:43am UTC](https://community.unix.com/t/help-with-replace-character-based-on-specific-location/284399/5 "2011-03-14T02:43:44Z")

</div>

Try this,

```nohighlight
#!/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

```nohighlight
substr($_,($start-1),($end-$start+1))="X" x ($end-$start);

```

---

<div class="post-metadata">

**Author:** ![perl\_beginner](https://community.unix.com/letter_avatar/perl_beginner/32/5_5575768a8748004e209b776fc1b2916d.png) [@perl\_beginner](https://community.unix.com/u/perl_beginner)\
**Post date:** [March 18, 2011, 3:17am UTC](https://community.unix.com/t/help-with-replace-character-based-on-specific-location/284399/6 "2011-03-18T03:17:30Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![pravin27](https://community.unix.com/letter_avatar/pravin27/32/5_5575768a8748004e209b776fc1b2916d.png) [@pravin27](https://community.unix.com/u/pravin27)\
**Post date:** [March 18, 2011, 4:57am UTC](https://community.unix.com/t/help-with-replace-character-based-on-specific-location/284399/7 "2011-03-18T04:57:11Z")

</div>

Try this,  
Your reffile column should match with input\_file.txt. I have added lowercase(lc). Hope this will resolved your problem.

```nohighlight
#!/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);

```
