Read a file and store contents to array

March 3, 2011 at 07:06:26
Specs: Linux
I have two files
File 1
ABC 23 787 779 798 444 90
DEF 12 765 899 343 988 34
GHI 23 987 876 545 987 45
JKL 12 987 565 876 543 89


File 2
ZBR 73 787 773 738 888 30
DEF 17 785 833 383 388 38
GHI 73 387 878 585 387 85
JKL 17 387 585 878 583 83

I need to read the contents and store them in array.

M trying
awk '{if (NR==1) split ($0,arr," ")}' File1, but this is not working. Can some one please advice.


See More: Read a file and store contents to array

Report •

#1
March 3, 2011 at 09:37:40
Your script stores the fields of line 1 of file1 in array, arr:

awk '{ if (NR==1) split ($0,arr)
}
END {
for (i in arr)
   print arr[i]
   }
' file1

# End script

Output:

23
787
779
798
444
90
ABC

Isn't that what you expect? I am not near my Linux box so I ran this on Solaris 9. Note that in the split function, split ($0,arr), that I am not using a field seperator since the default is white space, but your use of it should work fine.



Report •

#2
March 3, 2011 at 21:00:34
I want to do some comparisions between the values, this one isnt working. could you please advice.

awk '{ if (NR==1) split ($0,arr)}' file1
awk '{ if (NR==1) split ($0, app)}' file2
END '{for (i=2;i<6;i++)
{if (arr[i]>app[i])
printf("Hello")
}}'


Report •

#3
March 4, 2011 at 10:56:38
How about building the file1 array in the BEGIN section, build the file 2 array with the first line of file 2 (FNR gets set to 1 with the the new file. Probably you don't need the while loop in the BEGIN section since you only want the first line), and do your processing in the END section:

# UNTESTED
awk ' BEGIN {
   while ( getline < "file1" > 0 )
      {
      split ($0,arr)
      break  # stop after the first line
      }
}
{
if (FNR==1)
   split ($0, app)

}
END { ....
 } ' file2


Report •

Related Solutions

#4
March 7, 2011 at 03:04:22
Thanks a lot for this. But I need to store multiple values from the two files.
This is what I am trying to do currently, but its not working

T_FILE would be a file with today's date prefixed to it.
Y_FILE would be a file with yesterday's date.

awk '{if (NR==17) split ($0,arrt)}' ${T_FILE}
awk '{if (NR==18) split ($0,arrn)}' ${T_FILE}
awk '{if (NR==20) split ($0,arrd)}' ${Y_FILE )

awk '{
for(i=2;i<6;i++)
{if(arrt[i} >arrn [i]/10)
value++ //
}
if(value>0) // as there could be multiple times that arr[i]> arrn, but I want to print the message only once.
{
printf("process failed ")
count++
}
}'


Report •

#5
March 7, 2011 at 23:03:58
I would hope by this time you would realize that these are 3 different awk scripts:

awk '{if (NR==17) split ($0,arrt)}' ${T_FILE}
awk '{if (NR==18) split ($0,arrn)}' ${T_FILE}
awk '{if (NR==20) split ($0,arrd)}' ${Y_FILE )

In other words it's 3 different programs. This means array arrt knows nothing about array arrd, and knows nothing about array arrn. There is absolutely no link between those 3 scripts.

Similar to what I showed you before, the arrays have to be built inside one awk script:

# UNTESTED
awk ' BEGIN { cnt=0;
   while ( getline < "file1" > 0 )
      {
      cnt++
      if(cnt == 17)
         split ($0,arrt)
      if(cnt == 18)
         split ($0,arrn)
      }
}
{
# build the 3rd array from the second file
if(NR == 20)
   split ($0,arrd)

}
END {
   for(i=2;i<6;i++)
      {
      if(arrt[i] > arrn [i]/10 )
          {
          print "process failed"
          break
          }
     }
}
 ' file2
# end script

Do your check in the END block.  If only one 'process failed' is required, use break to break out of the loop (as I have) or an exit statement would stop the processing also. 


Report •

#6
March 8, 2011 at 05:52:37
Thanks so much. This work !!

But I have 1 more question ..
Instead of file1 , I need to give the variable name T_FILE . Could you please advice what is the correct syntax for this, where

T_DATE=`date +%Y%m%d`
T_FILE=output_${T_DATE}

while ( getline < "file1" > 0 )


Report •

#7
March 8, 2011 at 08:33:18
You can embed a shell variable in an awk script by surrounding the variable with a double quote-single quote-double quote: "'"$myfile"'"

myfile="file1"
# UNTESTED
awk ' BEGIN { cnt=0;
   while ( getline < "'"$myfile"'" > 0 )
   .
   .


Report •

#8
March 21, 2011 at 02:58:08
I need one mfore help. Could you please advice.
For the below code, if first=10 and second=9.9, then I get process failed. I need some way to rounf off decimal to nearest integer before comparing values.

for i in 1 2 3 4 5 6 7 8 9
do
if [ ${first[i]} -gt `${second[i]} / 10` ]
then
echo "Process failed"
break
fi
done


Report •

#9
March 21, 2011 at 08:57:50
In the Bourne and the pre-93 version of Korn shell, only integer arithmetic is allowed. A way to round a decimal number is to use awk:

#!/bin/ksh

second="9.9"
second=$(echo $second|awk ' { printf("%6.0f\n", $0) } ')
echo $second # second should equal 10


Report •

#10
March 29, 2011 at 04:07:52
I am getting some errors with synatx . Could you please advice. I need to sum the values and then do a compare

if [ "${arr[1]}" != "'`${arr[2]} + ${arr[3]}`'" ]

line 293: 20.2: command not found
+ '[' 20 '!=' ''\'''\''' ']'


Report •

#11
March 29, 2011 at 09:03:52
You are doing 2 things wrong:

1) To do integer comparison, use -ne; != is used for strings

2) Your integer arithmetic syntax is incorrect. This link might help you out.

#!/bin/ksh

arr[1]=5
arr[2]=2
arr[3]=3

if [ ${arr[1]} -ne $((${arr[2]} + ${arr[3]} )) ]
then
   echo "arr1 not equal arr2 and arr3"
fi


Report •

Ask Question