Help with Creating file based on conditions

Can anyone please assist?

I have a .txt file(File1.txt) and a property file(propertyfile.txt) . I have to read the vales from the property file and .txt file and create the output file(outputfile.txt) mentioned in the attachment. For each record in .txt file,the below mentioned values shall be added with the specified T and K Record.

Values:
T10 to T20 and K00 to K04 ( Read it from the propery file . TMAXRECORD and KMAXRECORD value will change in the future.

Note: File1.txt will contain around 9000 records. I have added few records in the sample file

What have you tried? Will propertyfile.txt always have 4 rows?

Yes, property file is having only 4 rows. I'm getting the values like this.

PROPERTY_FILE=propertyfile.txt
TMINRECORD=`grep "TMINRECORD=" $PROPERTY_FILE |sed "s/TMINRECORD=//g"` 
TMAXRECORD=`grep "TMAXRECORD=" $PROPERTY_FILE |sed "s/TMAXRECORD=//g"` 
KMINRECORD=`grep "KMINRECORD=" $PROPERTY_FILE |sed "s/KMINRECORD=//g"` 
KMAXRECORD=`grep "KMAXRECORD=" $PROPERTY_FILE |sed "s/KMAXRECORD=//g"` 

You can abbreviate that:

TMINRECORD=`sed -n "s/TMINRECORD=//p" $PROPERTY_FILE`
...

If you trust the file, you can even do

eval `cat $PROPERTY_FILE`

because it is in shell syntax.

1 Like

Where's the samples?

Sample files are attached in the begining.

Why don't you just source the file?

. /tmp/propertyfile.txt

will assign the four variables.

---------- Post updated at 22:31 ---------- Previous update was at 22:29 ----------

... and remove the DOS <CR> line terminators upfront!

Ok ! I need output mentioned in the attachment(ouputfile.txt). Can you help!

After having removed ALL the <CR>s from both files, this seemed to work:

. /tmp/propertyfile.txt
while read KW
        do eval echo "$KW${TMINRECORD:0:1}{${TMINRECORD:1}..${TMAXRECORD:1}} $KW${KMINRECORD:0:1}{${KMINRECORD:1}..${KMAXRECORD:1}}"
        done < /tmp/File1.txt | tr ' ' '\n'
00123T10
00123T11
00123T12
00123T13
etc...
1 Like

Can u please explain the code. I'm getting bad substitution error. i think eval command is not working.

I failed to mention that this needs a recent shell capable of brace expansion. A recent bash can do it out of the box, ksh needs the -B option set (afaik).

bash-4 will even retain the 00..04 (bash-3 will reduce to 0..4).
The following lets printf fold to lines:

#!/bin/bash
. propertyfile.txt
while read KW
do
  eval printf '%s\\n' $KW${TMINRECORD:0:1}{${TMINRECORD:1}..${TMAXRECORD:1}} $KW${KMINRECORD:0:1}{${KMINRECORD:1}..${KMAXRECORD:1}}
done < File1.txt

But still the eval is the evil.

I'm using KSH. I tried the above code and its not working. Any other solution?

ksh93 does it like bash-3. You seem to have the older ksh88.
Here is a solution with awk:

awk -F"=" '
NR==FNR {s[nn++]=$2; next}
{
  for (n=0; n<nn; n+=2) {
    letter=substr(s[n],1,1)
    startd=substr(s[n],2); endd=substr(s[n+1],2)
    lend=length(startd)
    for (d=startd; d<=endd; d++) printf "%s%s%0*d\n",$0,letter,lend,d
  }
}' propertyfile.txt File1.txt

On Solaris, take nawk or /usr/xpg4/bin/awk

I have tried your code and the output is not correct. the output should be like this. Please help !

00123T10
00123T11
00123T12
00123T14
.......
00123T20
00123K00
...
00123K04
06754T10
....
06754T20
06754K00
...
06754K04
....
next record

Which version of ksh? Did you set the -B option?

I tried with -B option and getting -B: bad option(s).
KSH version
Version M-11/16/88i

Have you tried something yourself?
Add a line that removes the WinDOS \r character.

awk -F"=" '
{ sub(/\r$/,"") }
NR==FNR {s[nn++]=$2; next}
{
  for (n=0; n<nn; n+=2) {
    letter=substr(s[n],1,1)
    startd=substr(s[n],2); endd=substr(s[n+1],2)
    lend=length(startd)
    for (d=startd; d<=endd; d++) printf "%s%s%0*d\n",$0,letter,lend,d
  }
}' propertyfile.txt File1.txt > output.txt

The output is now redirected to output.txt.

Thank u so much for your help! I have used nawk and the code is working, but one minor issue. The last K record is not inrementing. Can u please assist?
ex: current Output

00123T10
00123T11
00123T12
00123T14
............
00123T20
00123K00
06754T10
....
06754T20
06754K00

Expected output:

00123T10
00123T11
00123T12
00123T14
............
00123T20
00123K00
00123K01
00123K02
00123K03
00123K04
06754T10
....
06754T20
06754K00
06754K01
06754K02
06754K03
06754K04

Most awk versions treat "04" as a string rather than a number!
This seems to fix it:

     startd=substr(s[n],2); endd=substr(s[n+1],2)+0

By adding a zero, endd changes from 04 to 4, and the d<=endd becomes a comparison of numbers.

1 Like