Check for a substring in a String and move its ord

2019-08-25 03:11发布

问题:

main_string='{\"create\":false,\"name\":\"specified\",\"queue\":null,\"rules\":null},{\"create\":false,\"name\":\"primaryGroup\",\"queue\":null,\"rules\":null}, {\"create\":null,\"name\":\"secondaryGroupExistingQueue\",\"queue\":null,\"rules\":null},{\"create\":null,\"name\":\"default\",\"queue\":null,\"rules\":null}'
substring='\"create\":false,\"name\":\"specified\",\"queue\":null,\"rules\":null'

Now I do the comparison to see if substring is present in main string like below:

if [[ $main_string=~ "$substring" ]]; then

But I'm not sure how to move it's order. I tried but I don't know how can I achieve moving or maintaining order while moving in bash. (You can notice substring I selected, is the first string in main_string separated by ',' by other strings)

Any suggestion is welcome, thanks

回答1:

Can you get rid of the backslashes? There's no need to escape double quotes inside single quotes; the backslashes become literal backslashes. Without them, seeing as this looks like JSON data, you'd be best served by using jq rather than raw string manipulation.

main_string='{"create":false,"name":"specified","queue":null,"rules":null},{"create":false,"name":"primaryGroup","queue":null,"rules":null},{"create":null,"name":"secondaryGroupExistingQueue","queue":null,"rules":null},{"create":null,"name":"default","queue":null,"rules":null}'

jq is tailor made for processing JSON data. It can query it, filter it, manipulate it, generate new JSON data, whatever you like. Here's what happens with the most basic query, ., which simply spits out the input data unchanged. Notice how jq parses it and pretty prints it. All I had to do was pass in $main_string wrapped in square brackets:

$ jq -r '.' <<< "[$main_string]"
[
  {
    "create": false,
    "name": "specified",
    "queue": null,
    "rules": null
  },
  {
    "create": false,
    "name": "primaryGroup",
    "queue": null,
    "rules": null
  },
  {
    "create": null,
    "name": "secondaryGroupExistingQueue",
    "queue": null,
    "rules": null
  },
  {
    "create": null,
    "name": "default",
    "queue": null,
    "rules": null
  }
]

Here's how you could move an array element to the end:

$ jq '(.[] | select(.name=="specified")) as $elem | . - [$elem] + [$elem]' <<< "[$main_string]"
[
  {
    "create": false,
    "name": "primaryGroup",
    "queue": null,
    "rules": null
  },
  {
    "create": null,
    "name": "secondaryGroupExistingQueue",
    "queue": null,
    "rules": null
  },
  {
    "create": null,
    "name": "default",
    "queue": null,
    "rules": null
  },
  {
    "create": false,
    "name": "specified",
    "queue": null,
    "rules": null
  }
]

Explanation:

  • .[] loops over the four objects in the input array.
  • | is a lot like shell pipes. It's how you chain together steps in jq, feeding the output of each "filter" to the next.
  • select(.name=="specified") finds an object with the given name property.
  • as $elem saves the object in a variable.
  • . - [$elem] + [$elem] removes the object from the input array . and then adds it back at the end.

The end result is the object named "specified" is moved to the end of the array.



标签: bash shell