shash
December 15, 2015, 12:01pm
1
Hi All,
I 'm matching two files based on the first 2 columns and then populate other fields along with subtraction of few fields.
I have managed to get the output. However, is there a easier way in formatting the output as shown below instead of using additional printf for getting fixed width output file?
file1:
20150731|05|0000000132|000001182401644.77
20150731|08|0000000000|000000000000000.00
20150731|09|0000026468|000001189347835.97
20150731|10|0000332300|000013254549890.91
file2:
20150731|05|0000000100|000001000000000.00
20150731|09|0000099999|000009999999999.99
Code:
awk -F'|' 'FNR==NR{a[$1,$2]=$0;next}{if(b=a[$1,$2]){print $0"|"b}}' file2 file1 | awk 'BEGIN { FS="|"; OFS = "|";OFMT = "%.2f"} {print $1,$2,$3,$4,$7,$8,($3 - $7),($4 - $8)}'
Output:
20150731|05|0000000132|000001182401644.77|0000000100|000001000000000.00|32|182401644.77
20150731|09|0000026468|000001189347835.97|0000099999|000009999999999.99|-73531|-8810652164.02
Desired output is:
20150731|05|0000000132|000001182401644.77|0000000100|000001000000000.00|+0000000032|+000000182401644.77
20150731|09|0000026468|000001189347835.97|0000099999|000009999999999.99|-0000073531|-000008810652164.02
Thanks
Shash
Yoda
December 15, 2015, 12:33pm
2
Here is an awk approach:-
awk -F\| '
NR == FNR {
A[$1 FS $2] = $0
next
}
($1 FS $2) in A {
split(A[$1 FS $2], T)
m = ( $3 - T[3] ); f_m = ( m < 0 ? m * -1 : m )
n = ( $4 - T[4] ); f_n = ( n < 0 ? n * -1 : n )
printf "%s|%s|%s|%s|%s|%s|%c%010d|%c%018.2f\n", $1, $2, $3, $4, T[3], T[4], ( m > 0 ? "+" : "-" ), f_m, ( n > 0 ? "+" : "-" ), f_n
}
' OFS=\| file2 file1
1 Like
RudiC
December 15, 2015, 2:23pm
3
Bit simpler? Try
awk -F'|' '
{IX = $1 FS $2
}
FNR==NR {T3[IX] = $3
T4[IX] = $4
next
}
IX in T3 {printf "%s|%s|%s|%+011d|%+019.2f\n", $0, T3[IX], T4[IX], $3-T3[IX], $4-T4[IX]
}
' file2 file1
20150731|05|0000000132|000001182401644.77|0000000100|000001000000000.00|+0000000032|+000000182401644.77
20150731|09|0000026468|000001189347835.97|0000099999|000009999999999.99|-0000073531|-000008810652164.02
1 Like
shash
December 16, 2015, 11:58am
4
Many thanks Yoda & RudiC. Both your solutions worked!
---------- Post updated at 11:58 AM ---------- Previous update was at 04:04 AM ----------
Hi RudiC,
Is there a way to have thousand separator for numeric fields?
I tried using the following code but not able to use it in the code you provided
printf "%'.2f\n" 000001182401644.77
Can you please help?
Thanks
Shash
RudiC
December 16, 2015, 1:02pm
5
While the single-quote-flag is discussed in e.g. my (linux) man printf
it is not in FreeBSD. So its behaviour depends on the implementation.
bash (4.3.42(1)-release):
printf "%'.2f\n" 10000001182401644
10.000.001.182.401.644,00
awk:
awk 'BEGIN {printf "%\047.2f\n", 10000001182401644}'
awk: run time error: improper conversion(number 1) in printf("%'.2f
So - you need to test what happens on your system / tool...
1 Like