# Search and Replace by record position

**URL:** <https://community.unix.com/t/search-and-replace-by-record-position/298396>\
**Category:** Shell Programming and Scripting\
**Created:** [November 1, 2011, 6:30pm UTC](https://community.unix.com/t/search-and-replace-by-record-position/298396 "2011-11-01T18:30:17Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![macastor](https://community.unix.com/letter_avatar/macastor/32/5_5575768a8748004e209b776fc1b2916d.png) [@macastor](https://community.unix.com/u/macastor)\
**Post date:** [November 1, 2011, 6:30pm UTC](https://community.unix.com/t/search-and-replace-by-record-position/298396/1 "2011-11-01T18:30:17Z")

</div>

Hi All,  
I have a file that I would like to search for data and replace other data by record position number:

> [@](#):
>
> Example Data file:  
> 1112223333BRAD PIT PO BOX 111 PHOENIX AZ10567000025103111  
> 9994442222CLARK KENT PO BOX 222 LAS VEGAS NV27407000025102511  
> 7778884444STEVE JOBS PO BOX 444 SUN CITY AZ10473000015100111
> 
> Pos. 1-10 Phone#  
> Pos. 11-21 Name  
> Pos. 22-32 Address  
> Pos. 33-43 City  
> Pos. 44-45 State  
> Pos. 46-50 Zip  
> Pos. 51-56 Amt  
> Pos. 57-62 Date  
> Example data may not be properly aligned once i post thread..

Example search..  
search for "CLARK KENT" and replace Amt data "000025" with "000155"???

I'm able to search and replace unique data but, came to a stump when wanting to replace data that can be similar throughout other records.  
Example code of search routine..

```plaintext
$1="CLARK KENT"
$2="MJ WOO"

awk -v s="$1" -v r="$2" 'function convert(str) {return (length(str)>11)?substr(str,1,11):sprintf("%-11s",str)}
        {if ($0~s) sub(convert(s),convert(r))}1' FILENAME

```

---

<div class="post-metadata">

**Author:** ![CarloM](https://community.unix.com/letter_avatar/carlom/32/5_5575768a8748004e209b776fc1b2916d.png) [@CarloM](https://community.unix.com/u/CarloM)\
**Post date:** [November 1, 2011, 6:44pm UTC](https://community.unix.com/t/search-and-replace-by-record-position/298396/2 "2011-11-01T18:44:42Z")

</div>

Code tags preserve whitespace, quotes do not.

Try something like:

```nohighlight
sed '/CLARK KENT/s/^\(.\{50\}\).\{6\}/\1000155/' infile

```

---

<div class="post-metadata">

**Author:** ![macastor](https://community.unix.com/letter_avatar/macastor/32/5_5575768a8748004e209b776fc1b2916d.png) [@macastor](https://community.unix.com/u/macastor)\
**Post date:** [November 1, 2011, 7:07pm UTC](https://community.unix.com/t/search-and-replace-by-record-position/298396/3 "2011-11-01T19:07:48Z")

</div>

Hmmm? So I tested the sed command and didn't get any results. Am I doing something wrong??

> [@](#):
>
> $a="CLARK KENT"  
> $b="000099"
> 
> sed '/$a/s/^\(.\{50\}\).\{6\}/\1$b/' infile

---

<div class="post-metadata">

**Author:** ![CarloM](https://community.unix.com/letter_avatar/carlom/32/5_5575768a8748004e209b776fc1b2916d.png) [@CarloM](https://community.unix.com/u/CarloM)\
**Post date:** [November 1, 2011, 7:14pm UTC](https://community.unix.com/t/search-and-replace-by-record-position/298396/4 "2011-11-01T19:14:17Z")

</div>

You have to use double quotes on the sed command - the shell won't expand any variables in single quotes.

e.g on bash:

```nohighlight
$ cat x.sh
#!/bin/bash

a="CLARK KENT"
b="000099"

sed "/${a}/s/^\(.\{50\}\).\{6\}/\1${b}/" infile
$ ./x.sh
1112223333BRAD PIT PO BOX 111 PHOENIX AZ10567000025103111
9994442222CLARK KENT PO BOX 222 LAS VEGAS NV27407000099102511
7778884444STEVE JOBS PO BOX 444 SUN CITY AZ10473000015100111

```

---

<div class="post-metadata">

**Author:** ![macastor](https://community.unix.com/letter_avatar/macastor/32/5_5575768a8748004e209b776fc1b2916d.png) [@macastor](https://community.unix.com/u/macastor)\
**Post date:** [November 2, 2011, 10:26am UTC](https://community.unix.com/t/search-and-replace-by-record-position/298396/5 "2011-11-02T10:26:42Z")

</div>

Awesome! Thanks CarloM.  
Small problem though.... How would I pad data I replaced with spaces. Lest say I would like to search for name "CLARK KENT" and replace the city "LAS VAGAS" with "DEMING". When I do the sed command you showed me it shifts all the data to the left.

---

<div class="post-metadata">

**Author:** ![CarloM](https://community.unix.com/letter_avatar/carlom/32/5_5575768a8748004e209b776fc1b2916d.png) [@CarloM](https://community.unix.com/u/CarloM)\
**Post date:** [November 2, 2011, 10:36am UTC](https://community.unix.com/t/search-and-replace-by-record-position/298396/6 "2011-11-02T10:36:36Z")

</div>

You can use printf:

```nohighlight
#!/bin/bash

a="CLARK KENT"
b="DEMING"
b1="$(printf %-11s $b)"

sed "/${a}/s/^\(.\{32\}\).\{11\}/\1${b1}/" infile

```

Also, note that you need to change the 2 numbers in the regular expression to match the size of the preceding text and of the text you're replacing.

---

<div class="post-metadata">

**Author:** ![macastor](https://community.unix.com/letter_avatar/macastor/32/5_5575768a8748004e209b776fc1b2916d.png) [@macastor](https://community.unix.com/u/macastor)\
**Post date:** [November 2, 2011, 11:30am UTC](https://community.unix.com/t/search-and-replace-by-record-position/298396/7 "2011-11-02T11:30:22Z")

</div>

Thanks again CarloM, but now lets say I change "PHOENIX" to "LAS VEGAS" it separates "LAS" as a 20 characters and "VEGAS" as the next 20 characters. Sorry to keep making this harder than what it probably is... ☹

```nohighlight
a="BRAD PIT"
b="LAS VEGAS"
c="`(printf %-20s $b)`"

sed "/${a}/s/^\(.\{32\}\).\{11\}/\1${c}/" infile

```

---

<div class="post-metadata">

**Author:** ![CarloM](https://community.unix.com/letter_avatar/carlom/32/5_5575768a8748004e209b776fc1b2916d.png) [@CarloM](https://community.unix.com/u/CarloM)\
**Post date:** [November 2, 2011, 11:43am UTC](https://community.unix.com/t/search-and-replace-by-record-position/298396/8 "2011-11-02T11:43:52Z")

</div>

Should have been:

```nohighlight
b1=$(printf %-11s "$b")

```

(without quotes, printf will treat $b's expansion to `LAS VEGAS` as 2 parameters and just re-uses the format arg for both)

---

<div class="post-metadata">

**Author:** ![macastor](https://community.unix.com/letter_avatar/macastor/32/5_5575768a8748004e209b776fc1b2916d.png) [@macastor](https://community.unix.com/u/macastor)\
**Post date:** [November 2, 2011, 12:22pm UTC](https://community.unix.com/t/search-and-replace-by-record-position/298396/9 "2011-11-02T12:22:28Z")

</div>

Thank you so much CarloM! I was wondering though what is it in the printf command that pads the data with space? I was wondering if say I wanted to pad with zero's instead of spaces. 🙂

---

<div class="post-metadata">

**Author:** ![CarloM](https://community.unix.com/letter_avatar/carlom/32/5_5575768a8748004e209b776fc1b2916d.png) [@CarloM](https://community.unix.com/u/CarloM)\
**Post date:** [November 2, 2011, 12:40pm UTC](https://community.unix.com/t/search-and-replace-by-record-position/298396/10 "2011-11-02T12:40:20Z")

</div>

You can pad numbers with a format specifier like `%03d` , but iirc it doesn't work with strings - check the man page(s).

---

<div class="post-metadata">

**Author:** ![macastor](https://community.unix.com/letter_avatar/macastor/32/5_5575768a8748004e209b776fc1b2916d.png) [@macastor](https://community.unix.com/u/macastor)\
**Post date:** [November 2, 2011, 12:43pm UTC](https://community.unix.com/t/search-and-replace-by-record-position/298396/11 "2011-11-02T12:43:33Z")

</div>

Ok thanks again CarloM for all your help. 😃 Have a good day.

---

<div class="post-metadata">

**Author:** ![ctsgnb](https://community.unix.com/letter_avatar/ctsgnb/32/5_5575768a8748004e209b776fc1b2916d.png) [@ctsgnb](https://community.unix.com/u/ctsgnb)\
**Post date:** [November 2, 2011, 1:43pm UTC](https://community.unix.com/t/search-and-replace-by-record-position/298396/12 "2011-11-02T13:43:53Z")

</div>

To make it easier and safer, maybe you sould consider formating your file with a separator at first (here an example with colon ":" as separator)

```nohighlight
sed 's/PO BOX [0-9][0-9]*/:&:/;s/[^][^]*$/:&/;s/[]*:[]*/:/g' yourfile

```

All further processing can then easly be handled like changing the wanted field

```nohighlight
nawk -F: -vNAME="BRAD PIT" -vCITY="LAS VEGAS" '$0~NAME{$3=CITY}1'

```
