1

I'm having so much troubles trying to create a string that is the result of the concatenation of an array with a bit of addition every time it goes through the loop

# HERE IS THE VALUE OF CHANGELOG.JSON
# [
#   13,
#   14,
#   22
# ]

readarray -t lines <<<"$(cat $1/changelog.json | jq '.[]')"

echo "check if my array is filled"
echo ${lines[0]}
echo ${lines[1]}
echo ${lines[2]}
echo "my array is correctly filled.."

for i in ${!lines[@]}
do
    var2="$var2 | jq '.[$((($i+1)))]=${lines[$i]}'"
    echo "my var2 during loop: $var2"
done

echo "my var2 after loop $var2"

For some reasons, this script give me this as output

$ /bin/bash add-changelog.sh Blupods-front-v3/
check if my array is filled
13
14
22
my array is correctly filled..
'y var2 during loop:  | jq '.[1]=13
' | jq '.[2]=14loop:  | jq '.[1]=13
' | jq '.[3]=22'oop:  | jq '.[1]=13
' | jq '.[3]=22'op  | jq '.[1]=13

do you guys have any idea of how may i make it work ? i've already went through a lot of the solutions on stackoverflow and none of them worked (using += for concatenation) I've heard on other questions this is due to the fact that for/while loop create a subshell but even in the loop the variable doesn't get memorized.. also I don't have any pipe except for the read array at first.

EDIT: Here I add my expected result, maybe it will help you guys help me I am not trying to execute this command right away, i'm just trying to concat a string in a for loop the expected result should be this

echo $var2
| jq '.[1]=13' | jq '.[2]=14 | jq '.[3]=22'
5
  • What is var2="$var2 | jq '.[$((($i+1)))]=${lines[$i]}'" supposed to do? What is the initial value of var2? That assignment would not execute the pipeline if that is what you are expecting. It will simply assign the whole string to var2, and not the result of the pipeline execution. You need $(...) to execute the pipeline. Commented Nov 24, 2017 at 22:17
  • I do not want to execute it right away, i want to concatenate that string and only execute it outside of the loop at the end (the ultimate goal of this is to update a json file) there is no initial value to var2 Commented Nov 24, 2017 at 22:24
  • Please see the edit to see what i am trying to achieve Commented Nov 24, 2017 at 22:30
  • What do you want to do with $var2? There is likely a solution that doesn't require dynamically generating a pipeline of multiple calls to jq. Commented Nov 25, 2017 at 0:49
  • Something like jq --slurpfile cl changelog.json '.[:3] = $cl[]' original.json may do what you want. Commented Nov 25, 2017 at 0:53

2 Answers 2

2

It seems the values in the array have \r characters. You can remove them with tr -d '\r'. Actually I suggest to write like this:

lines=($(jq '.[]' < "$1"/changelog.json | tr -d '\r'))

And although your for-loop is correct, it can be improved too:

var2=
for i in ${!lines[@]}; do
    var2="$var2 | jq '.[$((i+1))]=${lines[i]}'"
done
Sign up to request clarification or add additional context in comments.

5 Comments

this is not doing anything because there is nothing inside "lines"
I managed to make it work by doing this instead lines=($(cat "$1"/changelog.json | jq '.[]' | tr -d '\r')) the solution you provided at first created a segmentation fault inside jq if you edit your answer i will approve it, Thanks a lot :)
@Rakiah how about lines=($(jq '.[]' < "$1"/changelog.json | tr -d '\r')) ? This should be equivalent, but without a useless cat ;-)
Yes, the second solution without the cat work just like the cat one, but there is still a problem, if my changelog.json file has an array of string containing spaces, the lines array contains much more key than one per value, for some reason the lines array also split everytime it encounter a space, do you have a solution for this aswell ? Thank you anyways
well a quick search find an answer for me if there is anyone with the same problem stackoverflow.com/questions/24628076/… this worked, and everything is fine now, Thank you janos
0

This might help instead if the respective line in the for loop.

var2="$(echo "$var2" | jq '.[$((($i+1)))]=${lines[$i]}')"

7 Comments

I am not trying to execute this command right away, i'm just trying to concat a string in a for loop the expected result should be this please see my edit for what I want to achieve
@Rakiah: Sorry, I now see what you were aiming for, thanks for your edit. I did some testing and figured, that -t for readarray didn't have the desired effects for me. In your case, this might case these strange line breaks in your output. However, variable substitution got me further. Could you try using ${lines[$i]//$'\n'/} in the body of your for loop instead of just ${lines[$i]}?
Thank you for your time, using this line var2="$var2 | jq '.[$((($i+1)))]=${lines[$i]//$'\n'/}'" I get this output 'y var2 during loop: | jq '.[1]=17 ' | jq '.[2]=13 '.[1]=17 ' | jq '.[3]=14'.[1]=17
but i do believe that readarray -t is the problem though, because with a normal array created like this array=(13 17 22) this give an output that look like much more what i want
@Rakiah: That looks better! Can you do var2="" before the loop?
|

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.