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?

7
  • 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 stackoverflow.com/questions/35005893/… Commented Jul 16, 2020 at 2: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 Commented Jul 16, 2020 at 2: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. Commented Jul 16, 2020 at 2: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. Commented Jul 16, 2020 at 2:13
  • 1
    Does this answer your question? Construct a command based upon a count variable in bash Commented Jul 16, 2020 at 6:06

4 Answers 4

3

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.

Sign up to request clarification or add additional context in comments.

Comments

2

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.

2 Comments

There are two different programs named yq, and their usage is different. The OP is using the one written in Go, not the one written in Python.
@CharlesDuffy Huh. That's annoying.
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[@]}"

Comments

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

Comments

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.