我有一个这样的文件
{"100":["0.00001","10","0.01"],
"101":["0.0001","100","0.1"],
"102":["1","1000","1"],
....
"103":["0.01","10000","10"]}
我想在每个数组内交换第二个数字与第三个数字,将其转换为
{"100":["0.00001","0.01","10"],
"101":["0.0001","0.1","100"],
"102":["1","1","1000"],
....
"103":["0.01","10","10000"]}
我该如何用 、 或其他方式做到这sed
一点awk
?
请注意第一个和最后一个记录中{
和的存在。}
谢谢
答案1
我建议避免使用面向文本的工具(如awk
orsed
等)解析 JSON 数据...
相反,请使用 JSON 解析器或依赖于 JSON 库的语言,例如perl
、python
等。
这是一个示例jq
:
<file jq '.[] |= (.[2] as $t | .[2] = .[1] | .[1] = $t)'
所有对象都替换为第三个和第二个数组元素的排列。请注意,中的数组jq
以索引开头0
。
答案2
比 jq 更详细的是使用具有可用 JSON 库的脚本语言:
ruby -rjson -e '
data = JSON.parse File.read ARGV.shift
data.transform_values! {|v| v[1], v[2] = v[2], v[1]; v}
puts JSON.pretty_generate data
' file.json
perl -E '
use Path::Tiny;
use JSON;
$json = JSON->new->utf8;
$data = $json->decode( path(shift)->slurp_utf8 );
while (($key, $val) = each %$data) {
($val->[1], $val->[2]) = ($val->[2], $val->[1]);
$data->{$key} = $val;
}
$json->canonical->indent;
say $json->encode($data);
' file.json
答案3
使用jq
及reverse
作用:
jq '.[][1:] |= reverse' file.json
或者
jq '.[][-2:] |= reverse' file.json
该表达式.[][1:]
选择包含文档中每个数组除第一个元素之外的所有元素的切片(.[][-2:]
显式选择每个数组中的最后两个元素)。这些可以使用 来反转reverse
。
一种可能更简单的方法:
通过按正确的顺序选择元素,按照我们想要的顺序显式重写数组:
jq 'map_values([ .[0], .[2], .[1] ])' file.json
这将使用原始数组中的元素按照挑选的顺序重新创建每个数组。