Reading text from a file

Guys,

I am trying to read text from a file, into arrays.

The format of the file is:

@DATABASE
femotest
@PACKAGE_SPECS
/usr/home/oracle92/sosa/scripts/test.pks
/usr/home/oracle92/sosa/scripts/rep.pks
@PACKAGE_BODIES
/usr/home/oracle92/sosa/scripts/rep.pkb
@PROCEDURES
@FUNCTIONS
@TRIGGERS
@VIEWS
@SQL_SCRIPTS

Where there can be any number of lines between each entry, I want to read these all into seperate arrays and a single variable for the database sid. I know how to grep for particular parts in the file, but its more getting the lines between them, could anyone give me some suggestions on how this can be done?

Again thanks.

The following script read all data into arrays (array name is entry name minus @) :

# Read alle ntries into arrays

entry=GARBAGE
while read record
do
   case "$record" in
      @*) entry=`expr substr "$record" 2 9999` ;;
      *) eval ${entry}[\${#${entry}[*]}]='$record' ;;
   esac
done < input_file

# Display arrays content

for array in DATABASE PACKAGE_SPECS PACKAGE_BODIES PROCEDURES FUNCTIONS TRIGGERS VIEWS SQL_SCRIPTS
do
   eval count=\${#${array}[*]}
   if [ $count -eq 0 ]
   then
      echo "${array} -> Empty"    
   else
      i=0
      while [ $i -lt $count ]
      do
         eval echo \"${array}[${i}]=\${${array}[${i}]}\"
         i=`expr $i + 1`
      done
   fi
done

Inputfile :

@DATABASE
femotest
@PACKAGE_SPECS
/usr/home/oracle92/sosa/scripts/test.pks
/usr/home/oracle92/sosa/scripts/rep.pks
@PACKAGE_BODIES
/usr/home/oracle92/sosa/scripts/rep.pkb
@PROCEDURES
procedure 1
procedure 2
@FUNCTIONS
function 1
function 2
@TRIGGERS
trigger 1
@VIEWS
view 1
view 2
@SQL_SCRIPTS
sql 1
sql 2
sql 3

Output:

DATABASE[0]=femotest
PACKAGE_SPECS[0]=/usr/home/oracle92/sosa/scripts/test.pks
PACKAGE_SPECS[1]=/usr/home/oracle92/sosa/scripts/rep.pks
PACKAGE_BODIES[0]=/usr/home/oracle92/sosa/scripts/rep.pkb
PROCEDURES[0]=procedure 1
PROCEDURES[1]=procedure 2
FUNCTIONS[0]=function 1
FUNCTIONS[1]=function 2
TRIGGERS[0]=trigger 1
VIEWS[0]=view 1
VIEWS[1]=view 2
SQL_SCRIPTS[0]=sql 1
SQL_SCRIPTS[1]=sql 2
SQL_SCRIPTS[2]=sql 3

Note: Leading and trailing spaces are not preserved.
If you want to keep them, try :

while IFS='' read record

Jean-Pierre.

Thanks very much aigles I didn't expect the full solution posted.

Aigles

Could you explain this section a little further?

) eval ${entry}[\${#${entry}[]}]='$record' ;;

and tbh the second line i am kinda lost with.

-- Edit, figured the first line out, i think!

Actually think i have figured them both out, thanks!

) ... ;;
Default case -> line doesn't start with @ -> Entry data
) eval ${entry}[\${#${entry}[]}]='$record' ;;
Generate and execute array assigment.
For example : FUNCTIONS[${#FUNCTIONS[
]}='input line'
${#FUNCTIONS[*]} is the actual number of elements of the array. Since the index of array start with 0, it's also the value of the next array element.

Jean-Pierre.

I have put the following:

readReleaseFile()
{
#Reads the contents of the release file

#Populate the arrays as required
init

entry=

while read record
do
case $record in
@*) entry=`expr substr $record 2 999`;;
) eval ${entry}[\${#${entry}[]}]=$record;;
esac
done < $releaseFile
}

But when I run it I get an error:

expr: syntax error
./release.sh[16]: [${#[*]}]=femotest: bad substitution

I know why the second line is giving the error, but the expr: syntax error I am not sure about.

I have also tried:

@*) entry=`expr substr "$record" 2 999`;;

Anyone know what syntax is wrong here?

Thanks

This portion of code is generated by the eval command :

*) eval ${entry}[\${#${entry}[*]}]='$record' ;;

Looks like variable entry not assigned.

  • Initialize entry with a GARBAGE value to catch lines found before an @ entry.
    text entry=GARBAGE while read record do
  • the syntax of the expr command seems valid.
    Add a trace option in the readReleaseFile function, that will permit to see the expr command that is executed.
    text readReleaseFile() { set -x

Jean-Pierre.

+ init
+ entry=GARBAGE
+ 0< /stuartTemp/ReleaseScripts/SQL/toRelease.txt
+ read record
+ + expr substr @database 2 999
expr: syntax error
entry=
+ read record
+ eval [${#[]}]=femotest
./release.sh[16]: [${#[
]}]=femotest: bad substitution

I was thinking that perhaps my version does not support substr in expr expressions, how can i check this?

You can test your expr command with :

expr substr abcdef 2 3    # Gives bcd
expr substr @DATABASE 2 3 # Gives DAT
expr substr @DATABASE 2 999 # Gives DATABASE

The expr command can be replaced by cut :

entry=`echo "$record" | cut -c2-`

Jean-Pierre.

Thanks aigles, the cut option worked.

When i done the expr option, it gave the same error at the terminal window, however what I find weird is that the substr option appears in the man pages.

aww well, thanks again.

Hi

I am still working on this problem, well actually just getting back round to it, anyway I have implemented the arrays as suggested above but instead of having the output as above, i.e. with line: eval echo \"${array}[${i}]=\${${array}[${i}]}\"

I just want to place each value within the array into a variable.

Currently my code is:

for arrays in packageSpecs packageBodies procedures triggers functions views sqlScripts
do
eval count=\${#${arrays}[*]}

  if [ $count -eq 0 ]
  then
     echo "$\{arrays\}: Nothing to be verified"
  else
     counter=0

     while [ $counter -lt $count ]
     do
        eval echo \\"\\$\{$\{arrays\}[$\{counter\}]\}\\"

        fileToVerify=eval \\$\{$\{arrays\}[$\{counter\}]\}\\

        echo "Verifing: $fileToVerify"

        counter=$counter\+1
     done
  fi

But this does not work as expected, I know its the line: fileToVerify=eval \${${arrays}[${counter}]}\ that gives me issues and have tried different ways to write this line looking at what agiles done above, can someone please tell me what I am doing wrong? Thanks

Try to change :

fileToVerify=eval \${${arrays}[${counter}]}\

by

eval fileToVerify=\${${arrays}[${counter}]}

Please use [CODE] tag...

Jean-Pierre.

Thanks (again), worked a treat.

Sorry never seen the [code] tags, will use next time :slight_smile: