awk or sed to change column value in a file

2020-05-04 12:26发布

问题:

I have a csv file with data as follows

16:47:07,3,r-4-VM,230000000.,0.466028518635,131072,0,0,0,60,0
16:47:11,3,r-4-VM,250000000.,0.50822578824,131072,0,0,0,0,0
16:47:14,3,r-4-VM,240000000.,0.488406067907,131072,0,0,32768,0,0
16:47:17,3,r-4-VM,230000000.,0.467893525702,131072,0,0,0,0,0

I would like to shorten the value in the 5th column.

Desired output

16:47:07,3,r-4-VM,230000000.,0.46,131072,0,0,0,60,0
16:47:11,3,r-4-VM,250000000.,0.50,131072,0,0,0,0,0
16:47:14,3,r-4-VM,240000000.,0.48,131072,0,0,32768,0,0
16:47:17,3,r-4-VM,230000000.,0.46,131072,0,0,0,0,0

Your help is highly appreciated

回答1:

awk '{$5=sprintf( "%.2g", $5)} 1' OFS=, FS=, input

This will round and print .47 instead of .46 on the first line, but perhaps that is desirable.



回答2:

Try with this:

cat filename | sed 's/\(^.*\)\(0\.[0-9][0-9]\)[0-9]*\(,.*\)/\1\2\3/g'

So far, the output is at GNU/Linux standard output, so

cat filename | sed 's/\(^.*\)\(0\.[0-9][0-9]\)[0-9]*\(,.*\)/\1\2\3/g' > out_filename

will send the desired result to out_filename



回答3:

If rounding is not desired, i.e. 0.466028518635 needs to be printed as 0.46, use:

cat <input> | awk -F, '{$5=sprintf( "%.4s", $5)} 1' OFS=,

(This can another example of Useless use of cat)



回答4:

You want it in perl, This is it:

perl -F, -lane '$F[4]=~s/^(\d+\...).*/$1/g;print join ",",@F' your_file

tested below:

> cat temp
16:47:07,3,r-4-VM,230000000.,0.466028518635,131072,0,0,0,60,0
16:47:11,3,r-4-VM,250000000.,10.50822578824,131072,0,0,0,0,0
16:47:14,3,r-4-VM,240000000.,0.488406067907,131072,0,0,32768,0,0
16:47:17,3,r-4-VM,230000000.,0.467893525702,131072,0,0,0,0,0
> perl -F, -lane '$F[4]=~s/^(\d+\...).*/$1/g;print join ",",@F' temp
16:47:07,3,r-4-VM,230000000.,0.46,131072,0,0,0,60,0
16:47:11,3,r-4-VM,250000000.,10.50,131072,0,0,0,0,0
16:47:14,3,r-4-VM,240000000.,0.48,131072,0,0,32768,0,0
16:47:17,3,r-4-VM,230000000.,0.46,131072,0,0,0,0,0


回答5:

sed -r 's/^(([^,]+,){4}[^,]{4})[^,]*/\1/' file.csv


回答6:

This might work for you (GNU sed):

sed -r 's/([^,]{,4})[^,]*/\1/5' file

This replaces the 5th occurence of non-commas to no more than 4 characters length.