2

I have a yq read command as below,

groups=$(yq read  generated/identity-mapping.yaml "iamIdentityMappings.[0].groups")

It reads iamIdentityMappings from below yaml:

iamIdentityMappings:
- groups:
  - Appdeployer
  - Moregroups

It stores group as below,

- Appdeployer
- Moregroups

But I want to store groups as below.(comma separated values)

groups="Appdeployer","Moregroups"

How to do this in bash?

Rad4
  • 1,936
  • 8
  • 30
  • 50
  • Are you sure you don't want to use a native bash array instead? For that, convert to json (which we know from other questions that you already know how to do) and use readarray/mapfile with jq as given in https://stackoverflow.com/questions/35005893/convert-a-json-array-to-a-bash-array-of-strings – Charles Duffy Jul 16 '20 at 02:07
  • Sorry..not sure what you mean by native bash array..But I want as comma separated values so I can pass it in one eksctl command..Only this csv is working – Rad4 Jul 16 '20 at 02:09
  • I'd need to know what the command you're calling is to know if that actually is the right tool for the job. Strings are not arrays, and pretending that they are is a common source of bugs. See [BashFAQ #5](https://mywiki.wooledge.org/BashFAQ/005). – Charles Duffy Jul 16 '20 at 02:10
  • 1
    That said, if you set `IFS=,`, `"${somearray[*]}"` will convert a native bash array to a comma-separated string, which it sounds like is what you want. – Charles Duffy Jul 16 '20 at 02:13
  • @CharlesDuffy ..you are amazing..thankyou :) – Rad4 Jul 16 '20 at 02:16
  • 1
    Does this answer your question? [Construct a command based upon a count variable in bash](https://stackoverflow.com/questions/62926693/construct-a-command-based-upon-a-count-variable-in-bash) – user1934428 Jul 16 '20 at 06:06
  • Comparing this to [your other post on the same problem](https://stackoverflow.com/questions/62926693/construct-a-command-based-upon-a-count-variable-in-bash), I suspect it's an [XY Problem](http://xyproblem.info/). Combine these questions into one [*clear* question](https://stackoverflow.com/help/asking) and you'll likely get a better answer, faster. – Paul Hodges Jul 16 '20 at 13:55

4 Answers4

3

yq is just a wrapper for jq, which supports CSV output:

$ groups="$(yq -r '.iamIdentifyMappings[0].groups | @csv' generated/identity-mapping.yaml)"
$ echo "$groups"
"Appdeployer","Moregroups"

The yq invocation in your question just causes an error. Note the fixed version.

Shawn
  • 47,241
  • 3
  • 26
  • 60
1

Use mapfile and format a null delimited list with yq:

mapfile -d '' -t groups < <(
  yq -j '.iamIdentityMappings[0].groups[]+"\u0000"' \
  generated/identity-mapping.yaml
)
typeset -p groups

Output:

declare -a groups=([0]="Appdeployer" [1]="Moregroups")

And now you can fulfill this second part of your question: Construct a command based upon a count variable in bash

# Prepare eksctl's arguments into an array
declare -a eksctl_args=(create iamidentitymapping --cluster "$name" --region "$region" --arn "$rolearn" )

# Read the groups from the yml into an array
mapfile -d '' -t groups < <(
  yq -j '.iamIdentityMappings[0].groups[]+"\u0000"' \
  generated/identity-mapping.yaml
)

# Add arguments per group
for group in "${groups[@]}"; do
  eksctl_args+=(--group "$group")
done

# add username argument
eksctl_args+=(--username "$username")

# call eksctl with its arguments
eksctl "${eksctl_args[@]}"
Léa Gris
  • 17,497
  • 4
  • 32
  • 41
1

yq 4.16+ now has a built in @csv operator:

yq e '.iamIdentityMappings.[0].groups | @csv' file.yaml

Note that @csv will only wrap values in quotes if needed (e.g. they have a comma).

If you want quotes, then sub then in and join with commas:

yq e '
   .iamIdentityMappings.[0].groups | 
   (.[] |= sub("(.*)", "\"${1}\"")) 
   | join(",")'

Disclaimer: I wrote yq.

mike.f
  • 1,586
  • 13
  • 14
0

yq version 3 is deprecated now and you can achieve the same output using version 4

#!/bin/bash

while IFS= read -r value; do
    groups_array+=($value)
done < <(yq eval '.iamIdentityMappings.[0].groups.[]' generated/identity-mapping.yaml)

printf -v comma_seperated '%s,' "${groups_array[@]}"
echo "${comma_seperated%,}"

This code prints the comma seperated values as you wanted

mbr1411
  • 1
  • 1