Search and Replace by record position

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

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..

$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

Code tags preserve whitespace, quotes do not.

Try something like:

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

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

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

e.g on bash:

$ 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

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.

You can use printf:

#!/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.

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... :frowning:

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

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

Should have been:

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)

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. :slight_smile:

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

1 Like

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

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)

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

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