From: romy on

Hi, I need help in developing a Unix script to implement the following
logic:

The input file will be a comma separated field with three columns
( please see below ).
The logic :
for each code2 ( 2nd col of the input file ) do the following :
1. If record exists for both 58 and 69, pass both records in o/p file
and bypass record with 4, if present.
2. If there are records for code1 ‘58’ & ‘4’ pass the ‘58’ record in o/
p file and create the ‘4’ record with code1 ‘69’.
3.If there are records for code1 ‘69’ & ‘4’ pass the ‘69’ record in o/
p file and create the ‘4’ record with code ‘58’ in o/p file.
4. If there is only a code ‘4’ record, create that record under both
‘58’ & ‘69’ and pass to o/p file.

I/P:
=============
4,A107,some text
58,A107,some text
69,A107,some text
58,A116, some text1
4,A116, some text2
4,A119, some text3
69,A119,some text4
4,A123, some text5

O/P:
======
58,A107,some text
69,A107,some text
58,A116,some text1
69,A116,some text2
58,A119,some text3
69,A119,some text4
58,A123,some text5
69,A123,some text5

Any help would be appreciated !
From: pk on
romy wrote:

> The logic :
> for each code2 ( 2nd col of the input file ) do the following :
> 1. If record exists for both 58 and 69, pass both records in o/p file
> and bypass record with 4, if present.
> 2. If there are records for code1 ?58? & ?4? pass the ?58? record in o/
> p file and create the ?4? record with code1 ?69?.
> 3.If there are records for code1 ?69? & ?4? pass the ?69? record in o/
> p file and create the ?4? record with code ?58? in o/p file.
> 4. If there is only a code ?4? record, create that record under both
> ?58? & ?69? and pass to o/p file.
>
> I/P:
> =============
> 4,A107,some text
> 58,A107,some text
> 69,A107,some text
> 58,A116, some text1
> 4,A116, some text2
> 4,A119, some text3
> 69,A119,some text4
> 4,A123, some text5
>
> O/P:
> ======
> 58,A107,some text
> 69,A107,some text
> 58,A116,some text1
> 69,A116,some text2
> 58,A119,some text3
> 69,A119,some text4
> 58,A123,some text5
> 69,A123,some text5

If I understand correctly, assuming the only possible values for the first
column are 4, 58 and 69, assuming their possible combinations are only those
you described, and assuming records that have the same second field are
consecutive:

awk -F ', *' '

function do_print(a, l58, l69){
if((58 in a)&&(69 in a)){
l58=a[58]; l69=a[69]
}else if((58 in a)&&(4 in a)){
l58=a[58]; l69=a[4]
}else if((69 in a)&&(4 in a)){
l58=a[4]; l69=a[69]
}else if(4 in a){
l58=l69=a[4]
}
print "58,"l58; print "69,"l69
}

$2!=p{
if(p){
do_print(a)
delete a[4];delete a[58];delete a[69]
}
}

{p=$2; a[$1]=p","$3}

END{
if(p){
do_print(a)
}
}' file

Seems to work with your sample input.
From: Bit Twister on
On Mon, 8 Feb 2010 13:27:42 -0800 (PST), romy wrote:


net etiquette/News Group tip:

Please set your Usenet client/editor to line wrap at 72 characters.

1. Some people may not respond to your request for help, if they have
to re-format your request to follow the guidelines.

2. The extra space is then used by news client for adding reply depth
indicators at front of line without wrapping the text.

http://www.anta.net/misc/nnq/ has a link
Writing style on Usenet - how to make your posts really easy to read

http://www.faqs.org/faqs/usenet/posting-rules/part1/ suggest under 72.

http://www.catb.org/~esr/faqs/smart-questions.html#formats
indicats e-mail, applies to Usenet.

Feel free to use any Usenet group ending in .test to test your news
client settings.




> Hi, I need help in developing a Unix script to implement the following
> logic:
>
> The input file will be a comma separated field with three columns
> ( please see below ).

> The logic : for each code2 ( 2nd col of the input file ) do the
> following :

> 1. If record exists for both 58 and 69, pass both records in o/p
> file and bypass record with 4, if present.

> 2. If there are records for code1 '58' & '4' pass the '58' record in
> o/ p file and create the '4' record with code1 '69'

> 3.If there are records for code1 '69' & '4' pass the '69' record in
> o/ p file and create the '4' record with code '58' in o/p file.

> 4. If there is only a code '4' record, create that record under both
> '58' & '69' and pass to o/p file.

Looking at your requirements and your data I think I may have become
confused as to which column is which. All requirements may not be in
the code. :-)

But, here is a quick kludge which is un-tested. Feel free to start
hacking around with it.


_op_fn=op.data
_ip_fn=ip.data

while read -r _line ; do
set -- $line
_code1=$1
_code2=$2
shift 2
_text="$1"

_process_it=1
#***************************
#* requirement 1 processing
#***************************
_58_2exist=$(grep -c ',58,' $_ip_fn)
_69_2exist=$(grep -c ',69,' $_ip_fn)
_both_58_69=0

if [ $_58_exist -ne 0 ] ; then
if [ $_69_exist -ne 0 ] ; then
_both_58_69=1
fi
fi



case $_code2 in
58)
if [ $_both_58_69 -eq 1 ] ; then
echo "$_code1,$_code2,$_text" >> $_op_fn
_process_it=0
fi
;;
69)
if [ $_both_58_69 -eq 1 ] ; then
echo "$_code1,$_code2,$_text" >> $_op_fn
_process_it=0
fi
;;
4)
if [ $_both_58_69 -eq 0 ] ; then
echo "58,$_code2,$_text" >> $_op_fn
echo "69,$_code2,$_text" >> $_op_fn
_process_it=0
fi
;;
*) ;;
esac

#***************************
#* requirement 2 processing
#***************************

if [ $_process_it -eq 1 ] ; then

_58_1exist=$(grep -c '^58,' $_ip_fn)
_69_1exist=$(grep -c '^69,' $_ip_fn)
_4_1exist=$(grep -c '^4,,' $_ip_fn)
_both1_58_4=0
_both1_69_4=0

if [ $_58_1exist -ne 0 ] ; then
if [ $_4_1exist -ne 0 ] ; then
_both_58_4=1
fi
fi

if [ $_69_1exist -ne 0 ] ; then
if [ $_4_1exist -ne 0 ] ; then
_both_69_4=1
fi
fi

case $_code1 in
58)
if [ $_both1_58_4 -eq 1 ] ; then
echo "$_code1,$_code2,$_text" >> $_op_fn
_process_it=0
fi
69)
if [ $_both1_69_4 -eq 1 ] ; then
echo "$_code1,$_code2,$_text" >> $_op_fn
_process_it=0
fi
;;
4)
if [ $_both1_69_4 -eq 1 ] ; then
echo "58,$_code2,$_text" >> $_op_fn
_process_it=0
fi
;;
*) ;;
esac
fi


done < $_ip_fn
From: Bit Twister on
On Mon, 8 Feb 2010 22:48:32 +0000 (UTC), Bit Twister wrote:

Opps, forgot to parse on comma.

set -- $line
should be set -- $(IFS=',' ; echo $_line)

You could change all
echo "$_code1,$_code2,$_text" >> $_op_fn
to
echo "$_line" >> $_op_fn
for a bit more clarity.
From: Ed Morton on
On Feb 8, 3:27 pm, romy <rav...(a)gmail.com> wrote:
> Hi, I need help in developing a Unix script to implement the following
> logic:
>
> The input file will be a comma separated field with three columns
> ( please see below ).
> The logic :
> for each code2 ( 2nd col of the input file ) do the following :
> 1. If record exists for both 58 and 69, pass both records in o/p file
> and bypass record with 4, if present.
> 2. If there are records for code1 ‘58’ & ‘4’ pass the ‘58’ record in o/
> p file and create the ‘4’ record with  code1 ‘69’.
> 3.If there are records for code1 ‘69’ & ‘4’ pass the ‘69’ record  in o/
> p file and create the ‘4’ record with code ‘58’ in o/p file.
> 4. If there is only a code ‘4’ record,  create that record under both
> ‘58’ & ‘69’ and pass to o/p file.
>
> I/P:
> =============
> 4,A107,some text
> 58,A107,some text
> 69,A107,some text
> 58,A116, some text1
> 4,A116, some text2
> 4,A119, some text3
> 69,A119,some text4
> 4,A123, some text5
>
> O/P:
> ======
> 58,A107,some text
> 69,A107,some text
> 58,A116,some text1
> 69,A116,some text2
> 58,A119,some text3
> 69,A119,some text4
> 58,A123,some text5
> 69,A123,some text5
>
> Any help would be appreciated !

$ cat file
4,A107,some text
58,A107,some text
69,A107,some text
58,A116,some text1
4,A116,some text2
4,A119,some text3
69,A119,some text4
4,A123,some text5
$
$ cat tst.awk
BEGIN{FS=","}
$2 != prevCode { codes[++codeCnt] = $2 }
{ rec[$1,$2]=$0; prevCode = $2 }
END {
for (i=1; i<=codeCnt;i++) {
code = codes[i]
if ( (4,code) in rec ) {
if ( ! ((58,code) in rec) ) {
rec[58,code] = rec[4,code]
sub(/4/,"58",rec[58,code])
}
if ( ! ((69,code) in rec) ) {
rec[69,code] = rec[4,code]
sub(/4/,"69",rec[69,code])
}
}
print rec[58,code]
print rec[69,code]
}
}
$
$ awk -f tst.awk file
58,A107,some text
69,A107,some text
58,A116,some text1
69,A116,some text2
58,A119,some text3
69,A119,some text4
58,A123,some text5
69,A123,some text5

You didn't say what do do if there was, say, a 58 but neither a 4 nor
a 69 so thats left as an exercise...

Ed.