0

Given a json that looks something like:

[{"id":1,"firstName":"firstName1","lastName":"lastName1"},
{"id":2,"firstName":"firstName2","lastName":"lastName2"},
{"id":3,"firstName":"firstName3","lastName":"lastName3"}]

What would be the best way to convert the id value from an int to a string and then saving the file?

I have tried:

echo "$(jq -r '[.[] | .id = .id|tostring]' test.json)" > test.json

But that seems to put each entry into a string and adds the backslashes

[
  "{\"id\":1,\"firstName\":\"firstName1\",\"lastName\":\"lastName1\"}",
  "{\"id\":2,\"firstName\":\"firstName2\",\"lastName\":\"lastName2\"}",
  "{\"id\":3,\"firstName\":\"firstName3\",\"lastName\":\"lastName3\"}"
]
1
  • Do not use process expansion ($(...)), redirect the output of jq directly to the output file (jq ... > test.json) Commented Mar 30, 2022 at 19:27

1 Answer 1

2

| has a lower priority than the assignment (=). The expression .id = .id | tostring is interpreted as (.id = .id) | tostring.

The assignment does change anything and can be removed. The script becomes [ .[] | tostring ], that explains the output (each object is serialized as JSON into a string).

The solution is to use parentheses to enforce the desired order of execution.
The command is:

jq '[ .[] | .id = (.id | tostring) ]' test.json

Do not use process expansion ($(...)) to compose an echo command line. It is inefficient and not needed.

Redirect the output of jq directly to a file. Use a different file than the input file (or it ends up destroying your data).

jq '[ .[] | .id = (.id | tostring) ]' test.json > output.json
Sign up to request clarification or add additional context in comments.

3 Comments

[.[] | …] can be shortened to map(…), and .id = (.id | …) can be shortened to .id |= …. Put together, you get jq 'map(.id |= tostring)'.
@pmf You are right. Put that into an answer.
You already gave the perfect explanation to OP's experience with their approach, and provided the proximate adjustment to achieve the desired result. My comment is just an improvement of the approach itself, and therefore doesn't really answer any question. However, if you want to give it more visibility, you could integrate it into your answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.