How to fetch values from a line in a file to variables in UNIX?

Hi,

I need to assign values from a lines in a file into variables in unix, i am using Korn shell.

I tried the below script from posts but i am unable to fetch every value in a variable.

#! /usr/bin/ksh

#for file in test.txt; do
IFS=$'\|'
I=1
while read -a val
do
echo "val[${I}]=${val[${I}]}"
I=` expr ${I} + 1 `
done < fs_mail.txt
#done

but i am getting error.

test_script_2.ksh[7]: read: -a: unknown option
Usage: read [-ACprsv] [-d delim] [-u fd] [-t timeout] [-n nchar] [-N nchar] [var?prompt] [var ...]

I tried this it worked but my file is pipe | separated ,variable are not as i expected.

#!/usr/bin/ksh
I=1
for WORD in $(cat test.txt); do
WORDS[$I]=$WORD
echo "WORDS[$I]=$WORD"
I=$((I + 1))
done

File will look like

line1|111|22|33|44|55|aa|bb|cc
line2|dd|ee|ff|gg|ii|jj|kk|ll|mm|nn|oo|pp

Could anyone Please advise, how to achive.

Thanks,
Regards,
karthikram

To start read -a is bash syntax. The equivalent ksh syntax is read -A

1 Like

Hi Scrutinizer,

Thanks for the quick reply read -A worked well for korn shell , i am unable to get the code properly. How to frame the variable loop to get each value from a line in a file.

like :

LINE_1_VALUE_1=111
LINE_2_VALUE_2=22
...
..
END OF LINE
LINE_2_VALUE_1=dd
LINE_2_VALUE_2=ee
...
...
..

Please give a gist or an idea/approach, if possible.

Thanks,
Regards,
karthikram

---------- Post updated at 10:45 AM ---------- Previous update was at 09:45 AM ----------

Hi,

i used IFS=$'\|' after that i able to find the script passing the individual value from a line in file to variable, but i need to read the end of the line , no sure how to , could anyone advise.

#!/usr/bin/ksh
IFS=$'\|'
I=0
for WORD in $(cat fs_mail.txt); do
WORDS[$I]=$WORD
echo "WORDS[$I]=$WORD"
I=$((I + 1))
done

Thanks,
Regards,
karthikram

This is a solution in bash, but you surely can devise a similar ksh thingy:

while IFS=\| read -a WORD; do echo -e ${#WORD[@]} "\t" ${WORD[@]}; done < file
9      line1 111 22 33 44 55 aa bb cc
13      line2 dd ee ff gg ii jj kk ll mm nn oo pp
1 Like

Hi , Thanks for looking into my request, Please help how to make loop inside the While loop to get the variables line by line , nothing is working for me.

In my above script it is taking the whole file into a variable and array element contains but differentiating between end of line and next line is not doing.

I am able to understand how many values does each line has using ${#WORD[@]}, Could any one please help how achive.

eg:

LINE_1[0]=AA
LINE_1[1]=BBB
.. 
..
LINE_2[0]=11
LINE_2[1]=22
..
..

for each line i need to create variable.

Thanks,
Regards,
karthikram

I used your file from post#1, and in my snippet WORD[0] = "line1; WORD[1] = "111", and so on. So - what else do you need?

Hi,

Thanks for workaround, Actually my requirement is to get values from line by line in a file and assign to variable, it is good that for each line if there is separate variable also, from the above idea provided.

That is

initially my file looks like this

111|22|33|44|55|aa|bb|cc
dd|ee|ff|gg|ii|jj|kk|ll|mm|nn|oo|pp
 
line1[0]=111
line1[1]=22
line1[2]=33
line1[3]=44
line1[4]=55
line1[5]=aa
line1[6]=bb
line1[7]=cc
 
line2[0]=dd
line2[1]=ee
line2[2]=ff
line2[3]=gg
line2[4]=ii
line2[5]=jj
line2[6]=kk
line2[7]=ll
line2[8]=mm
line2[9]=nn
line2[10]=oo
line2[11]=pp

I tried to fetch using the below script but, it is not getting in separate variable for each line instead , in single variable array has the entire file data.

script:

#!/usr/bin/ksh
IFS=$'\|'
I=0
for WORD in $(cat fs_mail.txt); do
WORDS[$I]=$WORD
echo "WORDS[$I]=$WORD"
I=$((I + 1))
done

but the output like :

WORDS[0]=111
WORDS[1]=22
WORDS[2]=33
WORDS[3]=44
WORDS[4]=55
WORDS[5]=aa
WORDS[6]=bb
WORDS[7]=cc
dd
WORDS[8]=ee
WORDS[9]=ff
WORDS[10]=gg
WORDS[11]=ii
WORDS[12]=jj
WORDS[13]=kk
WORDS[14]=ll
WORDS[15]=mm
WORDS[16]=nn
WORDS[17]=oo
WORDS[18]=pp

As Mr.RudiC provided snippet to get the number of values in the line using that how to make a loop to create each variable for each line.

Could anyone Please help me on this. I hope i have explained it correctly.

Thanks,
Regards,
karthikram

We get asked for this more often than you can imagine, but to date nobody's ever given a better reason for it than "it seemed like a good idea at the time". It's always silly -- how would you even use those variables? It'd take much eval madness to do a loop over variable1 ... variablen but a loop over an array is trivial.

1 Like

Hi Corona,

Thanks, Let me explain the reason, we are writting scripts and our superiors want them as HTML reports,
we have some security reasons so we are not allow html packages from db side, only solution we have is through shell script ,
files which are huge in row wise as well as column wise doesnt make any sense of making awk of some minimum 20 or above in a file,

so we required two loops in line wise as well as getting the data inside the line,

i came to heard that korn shell doesnt support multidimensional array ,

atleast single dimension is possible for each line if there is separate variable that could be possible to call them in array,

Thanks anyway, If any solution by chance if found or worked Please do let me know.

And If possible anyone could give example on "eval", hopefully that could be useful to me.

Thanks,
Regards,
karthikram

I get from that:
1) You have huge files
2) You must output HTML
3) You'd like multidimensional arrays

This actually sounds like exactly the kind of situation awk is meant for. It has things you can easily use as huge multidimensional arrays, and even if your lines are bigger than its line-length limit(which GNU/linux awk doesn't have, anyway) you can abuse the value of RS to read one field at a time instead.

Shell on the other hand is very poor for this. It doesn't have anything like multidimensional arrays, its performance is poor, and its variables are liable to be very limited in size.

I can show you more detail on this if you tell us more about what you want rather than details on the hoops you'd expected to jump through to do so.

1 Like

Whilst I fully accord with Corona688 about better not suboptimize but take the whole picture into account to find a good solution, here's a small bashism that might do what you're so eager for:

while IFS=\| read -a WORD$((++i)); do eval echo -e WORD$i "\\\t" $\{\#WORD$i[@]} "\\\t" $\{WORD$i[@]}; done < file
WORD1      9      line1 111 22 33 44 55 aa bb cc
WORD2      13      line2 dd ee ff gg ii jj kk ll mm nn oo pp

Your file's lines will be in WORD1, WORD2,... WORDn arrays.
Not sure if and/or how this works in ksh.

1 Like

Hi,

Thanks , the script worked well in ksh, now using your script each variable can be applied for each line ,
It is very helpful to me , But i am getting error while trying to use while loop or until after "eval" to get variable array's each element.
I will search the forum to get suitable result, meanwhile if anybody has solution it could be fine for me.
I should not expect more anyway i will workaround to get and if anyone knows Please do let me know.

$more test.txt
111|22|33|44|55|aa|bb|cc
dd|ee|ff|gg|ii|jj|kk|ll|mm|nn|oo|pp
$more test_script_6.ksh
#! /usr/bin/ksh
WORD=0
i=0
while IFS=$'\|' read -A WORD$((++i)); do
eval echo -e WORD$i "\\\t" $\{#WORD$i[@]} "\\\t" $\{WORD$i[@]}
echo -e "WORD2 WORD2[3]=${WORD2[3]}"
#j=0
#until [[ $j == "$\{#WORD$i[@]}" ]]; do
#echo -e WORD$i WORD$i[$j]=${WORD$i[$j]}
#j=$((j + 1))
#done
;done < test.txt
$./test_script_6.ksh
WORD1    8       111 22 33 44 55 aa bb cc
WORD2 WORD2[3]=
WORD2    12      dd ee ff gg ii jj kk ll mm nn oo pp
WORD2 WORD2[3]=gg
$more test_script_6.ksh
#! /usr/bin/ksh
WORD=0
i=0
while IFS=$'\|' read -A WORD$((++i)); do
eval echo -e WORD$i "\\\t" $\{#WORD$i[@]} "\\\t" $\{WORD$i[@]}
echo -e "WORD2 WORD2[3]=${WORD2[3]}"
j=0
until [[ $j == "$\{#WORD$i[@]}" ]]; do
echo -e WORD$i WORD$i[$j]=${WORD$i[$j]}
j=$((j + 1))
done
;done < test.txt
$ksh -x test_script_6.ksh
+ WORD=0
+ i=0
test_script_6.ksh: line 3: syntax error at line 9: `$' unexpected

tried with "while" also same error.

Thanks,
Regards,
karthikram

---------- Post updated at 01:05 PM ---------- Previous update was at 12:33 PM ----------

Hi Corona,

Thanks , i will try awk RS variable too, if this is achived and there wont be any loop again,

I wil try to come up and will post for review/suggestion.

Thanks,
Regards,
karthikram

Why - do you think - did I put that eval into the almost identical line 4 above your erroneous line? And, see and read again Corona688's post#8.

1 Like

Hi , Thanks , Now i understood that through shell it is not possible to make loop in main variable decomposing it to arrays of elements inside that each array further fetching array as array is not possible,

Please correct me if i am wrong this kind of multidimensional array and nested concept is available in PERL right.

I figured it out my script, Please let me know your suggestion or advise, how better this can be written.

$more test_script_8.ksh
#! /usr/bin/ksh

awk 'BEGIN{RS="\n";
FS="|";
}
{
print "<TR>";
for (i = 1; i <= NF; i++)
print "<TD>" $i "</TD>";
print "</TR>";
print "\n";
}' test.txt
$./test_script_8.ksh
<TR>
<TD>111</TD>
<TD>22</TD>
<TD>33</TD>
<TD>44</TD>
<TD>55</TD>
<TD>aa</TD>
<TD>bb</TD>
<TD>cc</TD>
</TR>


<TR>
<TD>dd</TD>
<TD>ee</TD>
<TD>ff</TD>
<TD>gg</TD>
<TD>ii</TD>
<TD>jj</TD>
<TD>kk</TD>
<TD>ll</TD>
<TD>mm</TD>
<TD>nn</TD>
<TD>oo</TD>
<TD>pp</TD>
</TR>

Thanks,
Regards,
karthikram

This sort of conversation has made many head-level dents in my wall before. "I need array arrays!" "What are you doing?" "I need array arrays!" "But why do you need your data arranged that way? For what purpose are you dumping all this stuff into memory?" "I need array arrays!" "...right."

I don't truly understand your question yet. You haven't given us a good enough sample of input and output for us to work with. But I suspect it may be entirely possible to get what you want in a multitude of ways, some with multidimensional arrays, some without them...

1 Like

Hi Corona,

Thanks i understood , loading n number of variable with n number of data in memory is not good approach for just basically accomplishing HTML report, This is Just for my self knowledge/ interest i just posted.

I will implement the awk RS approach that could you be fine, This is Nice and learnt something from this Post.

If anyone didnt get my query will change the way i will post going forward so that will be clear to answer my queries.

Thanks All for your Valuable inputs on my requirement.

Thanks,
Regards,
karthikram