Swap lines conditionally with awk

Viewed 73

I have the following file,

{
  "number": "12",
  "question": "Sample Question",
  "options": [
    {
      "text": "sample option 1",
      "type": "check",
      "isAnswer": "false"
    },
    {
      "text": "sample option 2",
      "type": "check",
      "isAnswer": "false"
    },
    {
      "text": "sample option 3",
      "type": "check",
      "isAnswer": "true"
    },
    {
      "text": "sample option 4",
      "type": "check",
      "isAnswer": "true"
    },
    {
      "text": "sample option 5",
      "type": "check",
      "isAnswer": "false"
    }
  ],
  "explanation": "sample explanation",
  "reference": "sample ref"
}

I would like to re-order the lines in such a way that type comes before text.

   {
      "type": "check",
      "text": "sample option 1",
      "isAnswer": "false"
    }

I know it is doable, I was able to swap some lines by using awk, but not getting the desired results. It seems to be an interesting problem, Can anyone help?

3 Answers

I was able to fix this with the following command.

awk -v r="text" -v o="type" ' $0 ~ o { s = 1 } $0 ~ r && ! s { cur = $0; getline; print; print cur; next; }  1 ' file.json
$ awk '$1~/^"text"/{txt=$0; next} {print} txt{print txt; txt=""}' file
{
  "number": "12",
  "question": "Sample Question",
  "options": [
    {
      "type": "check",
      "text": "sample option 1",
      "isAnswer": "false"
    },
    {
      "type": "check",
      "text": "sample option 2",
      "isAnswer": "false"
    },
    {
      "type": "check",
      "text": "sample option 3",
      "isAnswer": "true"
    },
    {
      "type": "check",
      "text": "sample option 4",
      "isAnswer": "true"
    },
    {
      "type": "check",
      "text": "sample option 5",
      "isAnswer": "false"
    }
  ],
  "explanation": "sample explanation",
  "reference": "sample ref"
}

This might work for you (GNU sed):

sed -E '/"text":/{N;/"type":/s/(.*)\n(.*)/\2\n\1/;P;D}' file

If the line following "text": contains "type":, swap the lines.

N.B. This may ripple a "text": line down a file if the there are more than one line containing "type": following it.

Related