如何交换 JSON 文件中的两个数组元素

如何交换 JSON 文件中的两个数组元素

我有一个这样的文件

{"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

我建议避免使用面向文本的工具(如awkorsed等​​)解析 JSON 数据...

相反,请使用 JSON 解析器或依赖于 JSON 库的语言,例如perlpython等。

这是一个示例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

使用jqreverse作用:

jq '.[][1:] |= reverse' file.json

或者

jq '.[][-2:] |= reverse' file.json

该表达式.[][1:]选择包含文档中每个数组除第一个元素之外的所有元素的切片(.[][-2:]显式选择每个数组中的最后两个元素)。这些可以使用 来反转reverse

一种可能更简单的方法:

通过按正确的顺序选择元素,按照我们想要的顺序显式重写数组:

jq 'map_values([ .[0], .[2], .[1] ])' file.json

这将使用原始数组中的元素按照挑选的顺序重新创建每个数组。

相关内容