How to fix this awk

I have a script which will mask the 9th and 15th column in a record starting with BPR.

The record looks like below before my script

BPR*C*160860.04*C*ACH*CTX*01*072000326*DA*1548843*3006968523**01*071000013*DA*5529085*100323*VEN

The record will be masked after my script parses this record

BPR*C*160860.04*C*ACH*CTX*01*072000326*DA*XXX8843*3006968523**01*071000013*DA*XXX9085*100323*VEN*

I do not want the '*' character at the end of the record at any point.
Below is my script

function chgrec(rec){
  debug=1
  z=split(rec,rarray,"*")
  element=10
  unChanged = rarray[element]
  lUnChg = length(unChanged)-3
  lastFour = substr(unChanged,lUnChg)
  initValue = rarray[element]
  gsub(/[0-9A-Za-z]/,"X",initValue)
  preFix = substr(initValue,1,lUnChg-1)
  element2=16
  unChanged2 = rarray[element2]
  lUnChg2 = length(unChanged2)-3
  lastFour2 = substr(unChanged2,lUnChg2)
  initValue2 = rarray[element2]
  gsub(/[0-9A-Za-z]/,"X",initValue2)
  preFix2 = substr(initValue2,1,lUnChg2-1)
  rec=""
  for (i=1;i<=z;i++){
#    printf("-->1:%s-->2:%s\n", i, rarray)> "/tmp/fftt";
     if (debug=0)
       {
        if (i==element)
          rec=rec sprintf("-->%s%s<--(%s)*", preFix, lastFour,rarray[element])
        else
        if (i==element2)
          rec=rec sprintf("-->%s%s<--(%s)*", preFix2, lastFour2,rarray[element2])
        else
            if (i==z)
            rec=rec sprintf("%s*", rarray)
       }
     else
       {
        if (i==element)
          rec=rec sprintf("%s%s*", preFix, lastFour,rarray[element])
        else
        if (i==element2)
          rec=rec sprintf("%s%s*", preFix2, lastFour2,rarray[element2])
        else
          rec=rec sprintf("%s*", rarray)
       }
  }

Something like this?

awk -F\* '/^BPR/{$10="XXX" substr($10,4);$16="XXX" substr($16,4)}1' OFS="*" file

Is there a way where you can find the problem in my script.
And also I should show only the last 4 characters in the 9th column and I should the mask the rest. You code works good but it masks only the 1st the 3 characters.

One way:

awk -F\* 'BEGIN{X="XXXXXXXXXX"}
/^BPR/{
  n=length($10)-4
  $10=substr(X,1,n) substr($10,n+1)
  n=length($16)-4
  $16=substr(X,1,n) substr($16,n+1)
}1' OFS="*" file

Thanks a lot Frank.. It worked.. I wanted to include this in my script and I did as shown below. But I get the syntax error as shown below. Any advise.

Below is the script awkMask

/./{
  type=substr($0,1,3)
  rec = $0
awk -F\* 'BEGIN{X="XXXXXXXXXX"}
/^BPR/{
n=length($10)-4
$10=substr(X,1,n) substr($10,n+1)
n=length($16)-4
$16=substr(X,1,n) substr($16,n+1)
}1' OFS="*" rec > output
}

I am trying to call this from the other script as shown below,

awk -f $base/scripts/awkMask $InputFile

I get the below error in my log file

  7834   syntax error The source line is 58.
  7835   The error context is
  7836          awk >>>  -F\ <<< * 'BEGIN{X="XXXXXXXXXX"}
  7837   awk: The statement cannot be correctly parsed.
  7838   The source line is 58.
  7839   syntax error The source line is 63.

Is this a snippet of an awk program?

/./{
  type=substr($0,1,3)
  rec = $0

You can't include the code in another awk program this way.

What would be the ideal way to have this in my script..

Without seeing the enire code, I won't be able to tell what is wrong with your logic, can you post the code?

This is script I have to mask the BPR record.

#Dynamically determine number of elements in BPR record looking for 10th and 16th element
/./{
type=substr($0,1,3)
rec = $0
awk -F\* 'BEGIN{X="XXXXXXXXXX"}
/^BPR/{
n=length($10)-4
$10=substr(X,1,n) substr($10,n+1)
n=length($16)-4
$16=substr(X,1,n) substr($16,n+1)
}1' OFS="*" rec > output
}

And I am calling this from a different script as shown below

exec 1>> $waulog
exec 2>> $waulog
awk -f $base/scripts/awkMask $Input

I wanted to have a script to mask the columns as I had mentioned above in my first post

Is output a defined variable? I don't know the logic behind the script, but you can try to replace my code with:

X="XXXXXXXXXX"
oldFS=FS
FS="\*"
while( getline < rec ) {
  if($0 ~ /^BPR/) {
    n=length($10)-4
    $10=substr(X,1,n) substr($10,n+1)
    n=length($16)-4
    $16=substr(X,1,n) substr($16,n+1)
  }
  print > "output"
}
FS=oldFS

The output of the code goes to the file "output".

I placed your code and it gives me syntax error as shown below,

rec = $0
X="XXXXXXXXXX"
oldFS=FS
FS="\*"
while( getline < rec ) {
  if($0 ~ /^BPR/) {
     n=length($10)-4
     $10=substr(X,1,n) substr($10,n+1)
     n=length($16)-4
     $16=substr(X,1,n) substr($16,n+1)
  }
  print > "/tmp/maskBank1fmt"
}
FS=oldFS

This is the error I get

 8471   syntax error The source line is 57.
  8472   The error context is
  8473           >>> while <<< ( getline < rec ) {
  8474   awk: Quitting
  8475   The source line is 57.

As early stated, without understanding the logic behind the script it's impossible to give an answer to your question.

The logic behind this script is in my first post where I am trying to mask the 9th and 15th column in a BPR record.

This is all I have in my script as I have shown above. I am trying to call this script from another script

You can save the awk code in a file (eg conv.awk) and call it in a shell script with:

sh conv.awk

In an awk program you can call it as:

system("sh conv.awk")

I tried as per your comments by renaming my file to name.awk and called it from a shell by

sh $base/scripts/name.awk $InputFile

It gives me the below error

  8754
  8755
  8756  /opt/webapp/rps/scripts/awkMask.awk[31]: Syntax error at line 32 : `{' is not expected.

Script below with the line number for your reference

    27  #Dynamically determine number of elements in BPR record looking for 10th and 16th element
    28  X="XXXXXXXXXX"
    29  oldFS=FS
    30  FS="\*"
    31  while ( getline < $0 ) {
    32  if ( $0 ~ /^BPR/ ) {
    33       n=length($10)-4
    34       $10=substr(X,1,n) substr($10,n+1)
    35       n=length($16)-4
    36       $16=substr(X,1,n) substr($16,n+1)
    37    }
    38    print > "/tmp/maskBank1fmt"
    39  }
    40  FS=oldFS

You must save this to a file (replace the filename at the end of the code with your own file):

awk -F\* 'BEGIN{X="XXXXXXXXXX"}
/^BPR/{
  n=length($10)-4
  $10=substr(X,1,n) substr($10,n+1)
  n=length($16)-4
  $16=substr(X,1,n) substr($16,n+1)
}1' OFS="*" file

Can I redirect the output of this to a file something like

awk -F\* 'BEGIN{X="XXXXXXXXXX"}
/^BPR/{
n=length($10)-4
$10=substr(X,1,n) substr($10,n+1)
n=length($16)-4
$16=substr(X,1,n) substr($16,n+1)
}1' OFS="*" $0 > "/tmp/maskBank1fmt"

Shure, why don't you try it out?
BTW $0 should be $1 if you give the inputfile as parameter like:

sh conv.awk filename

Yessssss.. I got it.. Thanks a lot Franklin..

Pfff... glad to know you got it working now.:slight_smile: