Shell Scripting

March 19, 2009 at 05:06:45
Specs: Windows XP
I want to replace few columns in one file with few columns in other files
File1:
1,"asd","sfdsfs",2,456,678
2,"qwe","zxcvbn",2,234,234

File2:
2,3
"cbc","buunny"
"xyz","suunny"

File1 is fixed width n is comma seperated.
First row of File2 signifies column numbers to be replaced in File1

Next rows have actual data to be replaced in those colunms in File1.

Can some one suggest me some solution to this problem using unix scripting?


See More: Shell Scripting

Report •


#1
March 19, 2009 at 12:36:53
This looks too much like homework, but I'll help you get started. The below script parses the comma delimited file2. It reads the first line retrieving the numbers of the two columns to change. The loop continues reading each row so you can process file1. You now have the column information required to process file1.

To process file1, either write another while loop parsing file1 similar to way file2 is processed. Or you can embed an awk script within the while loop to process file1.

#!/bin/ksh

fr=0
while IFS="," read arg1 arg2
do
   if [[ fr -eq 0 ]]
   then
     fcol="$arg1"
     scol="$arg2"
     fr=1
     continue
   fi
   #process file1
done < file2


Report •

#2
March 20, 2009 at 00:17:58
Thanks Buddy...I ll try it out.

Report •

#3
April 8, 2009 at 04:37:07
Following the ablove help i had build this script:

#!/bin/ksh
fc=1
fr=0
i=1
while IFS="," read arg1 arg2
do
if [[ fr -eq 0 ]]
then
fcol="$arg1"
scol="$arg2"
fr=1
continue
fi;
echo $arg2
#process file1
i=1
while IFS="," read abc[1] abc[2] abc[3] abc[4] abc[5] abc[6]
do
#echo i= $i
if [[ $fc -eq $i ]]
then
echo ${abc[$fcol]}
# set -A abc
set -A abc[$fcol]=$arg[1]
set -A abc[$scol]=$arg[2]
((i = ${i} + 1))
else ((i = ${i} + 1))
fi
done < file1.txt
echo $arg1
((fc = ${fc} + 1))
#echo fc= $fc
done < file3.txt
cat < file1.txt

But I am facing an issue here.

set -A abc[$fcol]=$arg[1]
set -A abc[$scol]=$arg[2]
here i m not able to set the values in required array.
the value remains same.
can anyone help me in this??


Report •

Related Solutions

#4
April 8, 2009 at 15:39:30
First, I have no idea what you are trying to do with the array. I can tell you below:

set -A abc[$fcol]=$arg[1]

$arg[1] is NOT an array element and you are treating it like it is.

Second, below is my solution not using an array. I'm assuming the output should be this:

1,"cbc","buunny",2,456,678
2,"xyz","suunny",2,234,234

What's tricky about my solution is knowing what this means:

eval col${fcol}='$arg1'

That means to evaluate the variable col${fcol} and set it to the contents of arg1. In the test data, it is either col2 or col3.
The answer is file1.org below.

#!/bin/ksh

cp file1 file1.org
fr=0
row=0
while IFS="," read arg1 arg2
do
   if [[ $fr -eq 0 ]]
   then
     fcol="$arg1"
     scol="$arg2"
     fr=1
     continue
   fi
   #process file1
   ((row+=1))
# process file1 once for every row in file2
   myrow=0
   while IFS="," read col1 col2 col3 col4 col5 col6
   do
      ((myrow+=1))
      if [[ $row -eq $myrow ]]
      then
         eval col${fcol}='$arg1'
         eval col${scol}='$arg2'
      fi
      echo "${col1},${col2},${col3},${col4},${col5},${col6}" >> file1.int
   done < file1.org
   mv file1.int file1.org

done < file2


Report •

#5
April 9, 2009 at 00:01:35
Hey Nails thats a great reply.
U solved my problem.
Now i need to analyze ur script n learn the scripting logic,
Thanks a load ,.,, :)

Report •

#6
April 17, 2009 at 05:48:54
#!/bin/ksh
NO_PARAM=$1
cp file1.txt file1.org
fr=0
row=0
while read line
do
TMP_COUNT=0
TMP_COUNT=` expr $TMP_COUNT + 0 `
while [ $TMP_COUNT -lt $NO_PARAM ]
do
TMP_COUNT=`expr $TMP_COUNT + 1`
echo $line | awk " BEGIN { FS = \",\" } { print \$$TMP_COUNT } " > tmp_sample.txt
TEMP1=`cat tmp_sample.txt`
arg[$TMP_COUNT]=$TEMP1
done

if [[ $fr -eq 0 ]]
then
i=0
while [ $i -lt $NO_PARAM ]
do
((i+=1))
param[$i]="$arg[$i]"
done
fr=1
continue
fi
#process file1
((row+=1))
# process file1 once for every row in file2
myrow=0
while IFS="," read col1 col2 col3 col4 col5 col6
do
((myrow+=1))
if [[ $row -eq $myrow ]]
then
x=0
while [ $x -lt $NO_PARAM ]
do
((x+=1))
eval col${param${x}}='$arg[$i]'
done
fi
echo "${col1},${col2},${col3},${col4},${col5},${col6}" >> file1.int
done < file1.org
mv file1.int file1.org

done < file2.txt


here it givin error in this line:
col${param${x}}="\$arg[\$i]": 0403-011 The specified substitution is not valid for this command.

can u suggest me how to do this..
i have made script parameterized to accept any number of columns for replacing


Report •

#7
April 17, 2009 at 09:48:18
I really have no idea what you are trying to do with the arrays. I don't even know what this means:

col${param${x}}="\$arg[\$i]"

Let me give you some pointers on your script:

1) there is no reason to add zero to TMP_COUNT; it's already 0:

TMP_COUNT=0
TMP_COUNT=` expr $TMP_COUNT + 0 `

2) Also, since you are using ksh, there is no reason to use expr to perform arithmetic. Instead of this:

TMP_COUNT=`expr $TMP_COUNT + 1`

use this:

((TMP_COUNT+=1)) # this is what I'm already in the script

of this:

((TMP_COUNT=TMP_COUNT+1))

3) You can NOT embed shell variables in awk like this:

awk " BEGIN { FS = \",\" } { print \$$TMP_COUNT } "

This link will show you how to do it:

http://www.tek-tips.com/faqs.cfm?fi...

4) To set the output of a command to a variable, use command substitution. Instead of this:

echo "$line" | awk '{ ..... } ' > tmp_sample.txt
TEMP1=`cat tmp_sample.txt`

do this:

TEMP1=$(echo "$line" | awk '{ ..... } ')

or this if you prefer back ticks:

TEMP1=`echo "$line" | awk '{ ..... } ' `


Report •


Ask Question