I have a file like this


I want to swap the second number with the third, inside each array, converting it into


How do I do that with sed, awk, or whatever?

Notice the existence of { and } at the first and last records.



I would advise to avoid parsing JSON data using text oriented tool like awk or sed, etc...

Instead use a JSON parser or a language that relies on a JSON library like perl, python, etc..

Here is an example with jq:

<file jq '.[] |= (.[2] as $t | .[2] = .[1] | .[1] = $t)'

All objects are replaced with the permutation of the 3rd and 2nd array element. Note that the arrays in jq start with index 0.


More verbose than jq would be to use a scripting language that has JSON libraries available:

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;
    say $json->encode($data);
' file.json

Using jq and its reverse function:

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


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

The expression .[][1:] selects slices containing all but the first element of each array in the document (.[][-2:] explicitly selects the last two element in each array). These are reversed using reverse.

In this case, you will get the same effect by using sort in place of reverse (use sort if it's actually sorting you want to do, and use .[] |= sort if you want to sort the arrays completely, not just the trailing or last two elements).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.