Need Shell Script for Array

Hi all,
I have an input file like below (a comma seperated file)

 345,12,10
 400,11,8
 328,1,3

I need to get the output as below ...

  record 345 sum is 12
  record 400 sum is 10
  record 328 sum is 1
  record 345 count is 10
  record 400 count is 8
  record 328 count is 3
  

I am trying to achieving it by reading the input file through array concept,i dnt have any idea on array concept in shell scripting

Thanks in advance
Sai

Hello Hemanth,

Following may help you in same. This should work and tested only on the provided format of input.

awk -F, '{for(i=1;i<2;i++){A[o]=A[o]?A[o] ORS "record " $i " sum is "  $(i+1):A[o] ORS "record " $i " sum is "  $(i+1);o++;A[o]=A[o]?A[o] ORS "record " $i " sum is "  $(i+2):"record " $i " sum is "  $(i+2);}}END{for(i in A){print A}}'  Input_file

Output will be as follows.

record 345 sum is 12
record 345 sum is 10
record 400 sum is 11
record 400 sum is 8
record 328 sum is 1
record 328 sum is 3

Thanks,
R. Singh

1 Like

Hi Singh,
Thanks for the reply,

In the output iam getting as

record 345 sum is 12
record 345 sum is 10
record 400 sum is 11
record 400 sum is 8
record 328 sum is 1
record 328 sum is 3

Like,everthing is coming with sum only i had count too iam getting sum text in count place too..

my output should be like

record 345 sum is 12
  record 400 sum is 10
  record 328 sum is 1
  record 345 count is 10
  record 400 count is 8
  record 328 count is 3

and can you please tell like wat is A[o]=A[o]?A[o] ORS exactly means....

thanks in advance,
Sai

---------- Post updated at 02:03 AM ---------- Previous update was at 01:59 AM ----------

hi ,
one more question will the loop work if the records in the input file increase...?

Hello Hemanth,

Could you please try following.

awk -F, '{for(i=1;i<2;i++){A[o]=A[o]?A[o] ORS "record " $i " sum is "  $(i+1):A[o] ORS "record " $i " sum is "  $(i+1);o++;A[o]=A[o]?A[o] ORS "record " $i " count is "  $(i+2):"record " $i " count is "  $(i+2);}}END{for(i in A){print A}}'  Input_file

Output will be as follows.

record 345 sum is 12
record 345 count is 10
record 400 sum is 11
record 400 count is 8
record 328 sum is 1
record 328 count is 3

Also for explaination for asked query is:

A[o]=A[o]?A[o] ORS "record " $i " count is "  $(i+2):"record " $i " count is "  $(i+2)
A[o]=A[o]  ## Store values in aray A whose index is variable o.
?               ## When condition if any in above command explaned is TRUE  do following actions.
A[o] ORS "record " $i " count is "  $(i+2) ## Keep value of A[o] as well as concatenate current value too.
:               ## If condition in first step if any is FALSE then do following.
"record " $i " count is "  $(i+2) ## Keep A[o]'s value to "record " $i " count is "  $(i+2)

Hope this helps, let me know if you have any queries.

Thanks,
R. Singh

Thanks for the explanation singh,

Final Query
you are displaying the output as

record 345 sum is 12
record 345 count is 10
record 400 sum is 11
record 400 count is 8
record 328 sum is 1
record 328 count is 3

can it be like below because i want the output as follows

record 345 sum is 12
  record 400 sum is 10
  record 328 sum is 1
  record 345 count is 10
  record 400 count is 8
  record 328 count is 3

Hello Hemath,

Could you please try following and let me know if this helps.

awk -F, '{for(i=1;i<2;i++){A[o]=A[o]?A[o] ORS "record " $i " sum is "  $(i+1):A[o] ORS "record " $i " sum is "  $(i+1);o++;A[o]=A[o]?A[o] ORS "record " $i " count is "  $(i+2):"record " $i " count is "  $(i+2);}}END{for(i in A){print A}}' test06 | sort -r -k 3,3

Also it will sort according to the keyword sum and count .

Thanks,
R. Singh

1 Like

hi thanks for the help,
I appreciate your skill.... :slight_smile:
one more doubt after sort you are specifying 3,3 right is it the records count...?
and one more will the script work if i increase the records count in input file...?

Hello Hemanth,

Following are the answers for your queries.
1: yes sort -r -k 3,3 means to sort the text in reverse order by taking the 3rd column as primary key.
2: yes, as I have mentioned in my very first post this code will work only on 3 fields seperated with , .

Hope this helps, let us know if you have any queries on same. If you have exact data in a different format please do let us know always from the very first post itself, it helps us too to help/guide.

Thanks,
R. Singh

With a simple input structure as in your sample, no matter how many lines (records) the file will contain, this might work:

awk '{print "record", $1, "sum is", $2; print "record", $1, "count is", $3; }' FS="," file
record  345 sum is 12
record  345 count is 10
record  400 sum is 11
record  400 count is 8
record  328 sum is 1
record  328 count is 3

For the order that you require, pipe it through sort as RavinderSingh13 proposed.

If all of the following are true:

  • you want the output order to be the same as the input order for both "sum" lines and "count" lines,
  • you don't really have leading spaces in your input file, and
  • you don't really want spaces at the start of each output line after the first output line,

you could try something like:

awk -F, '
{	printf("record %s sum is %s\n", $1, $2)
	r[NR] = $1
	c[NR] = $3
}
END {	for(i = 1; i <= NR; i++) printf("record %s count is %s\n", r, c)
}' file

which produces the output:

record 345 sum is 12
record 400 sum is 11
record 328 sum is 1
record 345 count is 10
record 400 count is 8
record 328 count is 3

Note that the input line:

400,11,8

in your sample input produces the output shown in red above, not the output:

record 400 sum is 10

that you said you wanted. If you really want the line above, you need to clearly explain what transformations are supposed to be applied to the data in the 2nd input field in your input records to produce the output you say you want.

If you want to try this script on a Solaris/SunOS system, change awk to /usr/xpg4/bin/awk or nawk .

hi ,
thanks for the reply..i just gave a example for the input file,

Can you please tell me like how to print the sum digit in currecy format ..?

like

record 345 sum is 12,345

Consider like in the input file the 345 record sum is 12345
i know that awk command do...

awk -F "," '{printf(fmt,value)}' FS=,OFS=, fmt="%'.2f"

can you please tell me like how to do that in the code you mentioned i didnt get that %s concept in the code

thanks in advance
sai

You'll have to divide the number by 100 and replace the "%s" with your desired format "%.2f". Note that not all versions will recognize the " ' " in the format string.

hi ,
in the below code

awk -F, '
{ printf("record %s sum is %s\n", $1, $2)
r[NR] = $1
c[NR] = $3
}
END { for(i = 1; i <= NR; i++) printf("record %s count is %s\n", r, c)
}' file

how can i represent to get the $2 value as currency format as in awk command its not accepting "%'.2f" as it contains ' symbol... can u help me on this like wat symbol i should add in the place of %s to get the desired format like 123,456 , 1,234 ..... :frowning:

Why don't you do it stepwise - like print the number divided by 100, print it with the "%.2f" format, and so on - and present us with the intermediate results so we see what goes wrong when.

As I said, the " ' " is not accepted on all systems/tools. Looks like yours is one of those. You'll now have to work on the resulting string if you insist on the thousands' separator.

Try:

awk -F, -v sq="'" '
{	printf("record %s sum is %" sq ".2f\n", $1, $2 / 100)
	r[NR] = $1
	c[NR] = $3
}
END {	for(i = 1; i <= NR; i++) printf("record %s count is %s\n", r, c)
}' file

which, with an input file containing:

345,12,10
400,11,8
328,1,3
111,1234567890,9

produces the output:

record 345 sum is 0.12
record 400 sum is 0.11
record 328 sum is 0.01
record 111 sum is 12,345,678.90
record 345 count is 10
record 400 count is 8
record 328 count is 3
record 111 count is 9

Alternatively, you could do it with externally defined complete format strings as in:

awk -F, '
{	printf(sum_format, $1, $2 / 100)
	r[NR] = $1
	c[NR] = $3
}
END {	for(i = 1; i <= NR; i++) printf(count_format, r, c)
}' sum_format="record %s sum is %'.2f\n" count_format="record %s count is %s\n" file

which produces the same output as the previous script.

This isn't the format you showed in your latest request (since you did not show a decimal point nor did you show two digits following the decimal point), but should do what you were trying to do with the format string %'.2f (assuming that the field 2 value in your input is a number of pennies rather than a number of dollars).

In the future PLEASE show us representative data that you want to process and corresponding output in the format you really want to get. If you would have shown us the actual diagnostic message(s) you got from awk we wouldn't have to guess whether your version of awk does not recognize a single quote as a printf numeric format flag or if you just didn't know how to include a single quote in a single quoted string.

You may try

[akshay@localhost tmp]$ cat infile
345,12,10
400,11,8
328,1,3
[akshay@localhost tmp]$ awk -F, 'BEGIN{A[1]="sum";A[2]="count"}FNR==1{fmt="Record %d "A[++i]" is %s\n"}{printf(fmt,$1,$(1+i))}' infile infile
Record 345 sum is 12
Record 400 sum is 11
Record 328 sum is 1
Record 345 count is 10
Record 400 count is 8
Record 328 count is 3