in [Shell]

Prev: nyd frequency
Next: chown problems
From: Ed Morton on 28 Apr 2010 10:19 On Apr 28, 8:29 am, ezhil <ezhi... (a)gmail.com> wrote:> Hi, > > I have a file with 4000 rows. The file consists of one filed (in a > single row) followed by 4 fields (multiple rows but not a fixed number > of rows). Something like: > > g1 > fs01 7 800 0.01 > fs03 7 805 0.5 > fs05 7 900 0.001 > g2 > as1 10 231 0.06 > as7 10 335 0.01 > as11 10 400 0.8 > > I would like to print g1 and then check for the minimum value in > column 4 and then print that minimum value. > > g1 > fs05 7 900 0.001 > g2 > as7 10 335 0.01 > > I was struggling a bit and then started trying with printing the min > value at least not the whole line (need to mark the line where I find > the min value but I don't know how to do this). > g1 > 0.001 > > So, I have tried, > > awk '{if(NF==1) {print $0} else {min=1; while(NF > 1) {if($4 < min) > min=$4}; {printf("%s\n", min)}} }' file1 > > This prints g1 and then stays blank for ever. Do I need to set up RS > and NF differently for this? Could you please help me to do this? > > Thanks in advance. > > Kind regards, > Ezhil awk ' NF == 1 { key = $0; next } (!(key in minVal)) || (minVal[key] < $4) { minVal[key] = $4 minRow[key] = $0 } END { for (key in minRow) print key ORS minRow[key] } ' file Ed.
From: ezhil on 28 Apr 2010 11:11 On Apr 28, 2:43 pm, pk <p... (a)pk.invalid> wrote:> ezhil wrote: > > I have a file with 4000 rows. The file consists of one filed (in a > > single row) followed by 4 fields (multiple rows but not a fixed number > > of rows). Something like: > > > g1 > > fs01 7 800 0.01 > > fs03 7 805 0.5 > > fs05 7 900 0.001 > > g2 > > as1 10 231 0.06 > > as7 10 335 0.01 > > as11 10 400 0.8 > > > I would like to print g1 and then check for the minimum value in > > column 4 and then print that minimum value. > > > g1 > > fs05 7 900 0.001 > > g2 > > as7 10 335 0.01 > > > I was struggling a bit and then started trying with printing the min > > value at least not the whole line (need to mark the line where I find > > the min value but I don't know how to do this). > > g1 > > 0.001 > > > So, I have tried, > > > awk '{if(NF==1) {print $0} else {min=1; while(NF > 1) {if($4 < min) > > min=$4}; {printf("%s\n", min)}} }' file1 > > > This prints g1 and then stays blank for ever. Do I need to set up RS > > and NF differently for this? Could you please help me to do this? > > Try this, assuming that the values in 4th columns are always less than 1000 > (arbitrary value; use another if it's not appropriate) > > awk 'NF==1{if(min)print minline;min=1000;print;next} > $4 < min {min=$4;minline=$0} > END{if(min)print minline}' file > > If you don't know how big the values can be, then you can do this to base > them only on real data: > > awk 'NF==1{if(min)print minline;min="";new = 1;print;next} > new { min = $4; minline = $0; new = 0; next } > $4 < min {min=$4;minline=$0} > END{if(min)print minline}' file > > this way, the value in the first line of each block is assumed to be the > initial minimum, and that may or not be changed by values in subsequent > lines. > You can do the same thing by using the dreaded getline: > > awk 'NF==1{if(min)print minline;print;getline;min=$4;minline=$0;next} > $4 < min {min=$4;minline=$0} > END{if(min)print minline}' file > > The caveat with the getline version is that it requires that each block has > at least one data line. Thanks a lot PK. It works nicely. Regards, Ezhil
From: ezhil on 28 Apr 2010 11:14 On Apr 28, 3:19 pm, Ed Morton <mortons... (a)gmail.com> wrote:> On Apr 28, 8:29 am, ezhil <ezhi... (a)gmail.com> wrote:> > > > > Hi, > > > I have a file with 4000 rows. The file consists of one filed (in a > > single row) followed by 4 fields (multiple rows but not a fixed number > > of rows). Something like: > > > g1 > > fs01 7 800 0.01 > > fs03 7 805 0.5 > > fs05 7 900 0.001 > > g2 > > as1 10 231 0.06 > > as7 10 335 0.01 > > as11 10 400 0.8 > > > I would like to print g1 and then check for the minimum value in > > column 4 and then print that minimum value. > > > g1 > > fs05 7 900 0.001 > > g2 > > as7 10 335 0.01 > > > I was struggling a bit and then started trying with printing the min > > value at least not the whole line (need to mark the line where I find > > the min value but I don't know how to do this). > > g1 > > 0.001 > > > So, I have tried, > > > awk '{if(NF==1) {print $0} else {min=1; while(NF > 1) {if($4 < min) > > min=$4}; {printf("%s\n", min)}} }' file1 > > > This prints g1 and then stays blank for ever. Do I need to set up RS > > and NF differently for this? Could you please help me to do this? > > > Thanks in advance. > > > Kind regards, > > Ezhil > > awk ' > NF == 1 { key = $0; next } > (!(key in minVal)) || (minVal[key] < $4) { > minVal[key] = $4 > minRow[key] = $0} > > END { > for (key in minRow) > print key ORS minRow[key]} > > ' file > > Ed. Hi Ed, Thanks. When I tried your solution, it prints the max value. Regards, Ezhil
From: pk on 28 Apr 2010 11:17 ezhil wrote: >> awk ' >> NF == 1 { key = $0; next } >> (!(key in minVal)) || (minVal[key] < $4) { >> minVal[key] = $4 >> minRow[key] = $0} >> >> END { >> for (key in minRow) >> print key ORS minRow[key]} >> >> ' file >> >> Ed. > > Hi Ed, > > Thanks. When I tried your solution, it prints the max value. Change the .... || (minval[key] < $4) to .... || ($4 < minval[key]) and it should be fine.
From: Ed Morton on 28 Apr 2010 14:24
On Apr 28, 10:14 am, ezhil <ezhi... (a)gmail.com> wrote:> On Apr 28, 3:19 pm, Ed Morton <mortons... (a)gmail.com> wrote:> > > > > > > On Apr 28, 8:29 am, ezhil <ezhi... (a)gmail.com> wrote:> > > > Hi, > > > > I have a file with 4000 rows. The file consists of one filed (in a > > > single row) followed by 4 fields (multiple rows but not a fixed number > > > of rows). Something like: > > > > g1 > > > fs01 7 800 0.01 > > > fs03 7 805 0.5 > > > fs05 7 900 0.001 > > > g2 > > > as1 10 231 0.06 > > > as7 10 335 0.01 > > > as11 10 400 0.8 > > > > I would like to print g1 and then check for the minimum value in > > > column 4 and then print that minimum value. > > > > g1 > > > fs05 7 900 0.001 > > > g2 > > > as7 10 335 0.01 > > > > I was struggling a bit and then started trying with printing the min > > > value at least not the whole line (need to mark the line where I find > > > the min value but I don't know how to do this). > > > g1 > > > 0.001 > > > > So, I have tried, > > > > awk '{if(NF==1) {print $0} else {min=1; while(NF > 1) {if($4 < min) > > > min=$4}; {printf("%s\n", min)}} }' file1 > > > > This prints g1 and then stays blank for ever. Do I need to set up RS > > > and NF differently for this? Could you please help me to do this? > > > > Thanks in advance. > > > > Kind regards, > > > Ezhil > > > awk ' > > NF == 1 { key = $0; next } > > (!(key in minVal)) || (minVal[key] < $4) { > > minVal[key] = $4 > > minRow[key] = $0} > > > END { > > for (key in minRow) > > print key ORS minRow[key]} > > > ' file > > > Ed. > > Hi Ed, > > Thanks. When I tried your solution, it prints the max value. > Sorry about that, as pk pointed out just switch the logic from ...|| (minVal[key] < $4) to ...|| (minVal[key] > $4) I am kinda surprised you couldn't figure that out though since the scripts only half a dozen lines. Is there some part of it that could use some explanation? Ed. |