我有一百个带三个字段的文件。每个人都看起来像这样(有更多行):
#time data1 data2
20 1.9864547484940e+01 -3.96363547484940e+01
40 2.164547484949e+01 -3.2363547477060e+01
60 1.9800047484940e+02 -4.06363547484940e+02
…
它们很重,有些需要1.5G。我想通过以较低的双精度保存最后两列并删除e+0?
项来减小它们的大小。例如,我想将上面的四行转换为:
#time data1 data2
20 19.865 -39.636
40 21.645 -32.364
60 198.00 -406.36
…
我用Google搜索并遇到CONVFMT
的{{1}}选项。但我不知道如何使用它,因为我真的不是awk的专家。这是在我的情况下使用的正确工具吗?如果是这样,我应该如何使用它?
我还想过编写一个C ++脚本,但直接命令行会很棒。
答案 0 :(得分:5)
我会使用awk的printf
函数:
awk 'NR==1;NR>1{printf "%d %.3f %.3f\n", $1, $2, $3}' file
以上命令输出:
#time data1 data2
20 19.865 -39.636
40 21.645 -32.364
60 198.000 -406.364
简短说明:
如果我们在第一行( NR ==记录数), NR==1
将评估为true
。如果一个条件没有跟着一个动作(在{}
之间),awk就会打印一行,在这种情况下是标题。
NR>1
在除第一行输入之外的所有其他行上评估为true
。接下来是一个动作,它使用printf
来实现所需的结果。
答案 1 :(得分:0)
你可以使用coreutils:
var get_object_id = (function() {
var generated_ids = 1;
var map = new Map();
return get_object_id;
function get_object_id(obj) {
if (map.has(obj)) {
return map.get(obj);
} else {
var r = generated_ids++;
map.set(obj, r);
return r;
}
}
})();
function tuple() {
return Array.prototype.map.call(arguments, get_object_id).join(',');
}
// Test
var data = [{x:3,y:5,z:3},{x:3,y:4,z:4},{x:3,y:4,z:7},
{x:3,y:1,z:1},{x:3,y:5,z:4}];
var map = new Map();
for (var i=0; i<data.length; i++) {
var p = data[i];
var t = tuple(p.x,p.y);
if (!map.has(t)) map.set(t,[]);
map.get(t).push(p);
}
function test(p) {
document.writeln((JSON.stringify(p)+' ==> ' +
JSON.stringify(map.get(tuple(p.x,p.y)))).replace(/"/g,''));
}
document.writeln('<pre>');
test({x:3,y:5});
test({x:3,y:4});
test({x:3,y:1});
document.writeln('</pre>');
输出:
head -n1 infile; tail -n+2 infile | while read n1 n2 n3; do printf "%d %.3f %.3f\n" $n1 $n2 $n3; done