Replacing YAML text with yq for a line containing single quotes

Viewed 1816

I'm trying to edit a YAML file to replace several particular values via a bash script.

For example, in the following file, I'd like to change the value of "command" from sh -c 'fabric-ca-server init -b admin:adminpw' to sh -c 'fabric-ca-server start -b admin:adminpw'

Before (Original File):

fabric-ca-server:
  image: hyperledger/fabric-ca:amd64-1.4.7
  container_name: fabric-ca-server
  ports:
    - "7054:7054"
  environment:
    - FABRIC_CA_HOME=/etc/hyperledger/fabric-ca-server
  volumes:
    - "./fabric-ca-server:/etc/hyperledger/fabric-ca-server"
  command: sh -c 'fabric-ca-server init -b admin:adminpw'

After (Desired Result):

fabric-ca-server:
  image: hyperledger/fabric-ca:amd64-1.4.7
  container_name: fabric-ca-server
  ports:
    - "7054:7054"
  environment:
    - FABRIC_CA_HOME=/etc/hyperledger/fabric-ca-server
  volumes:
    - "./fabric-ca-server:/etc/hyperledger/fabric-ca-server"
  command: sh -c 'fabric-ca-server start -b admin:adminpw'

Originally, I used sed like this: sed -i "10s/command:.*/command: sh -c 'fabric-ca-server start -b $UNVAR:$PWVAR'/" ./docker-compose.yaml Which works, but is pretty clumsy, since it requires the actual line number (which can change).

I discovered yq, which seems much more elegant, but I'm having trouble getting it to work here, because it interprets the -c as a flag. (I tried playing around with '--' to correct this, but didn't figure out how to get it working.)

yq w -i ./docker-compose.yaml fabric-ca-server.command sh -c 'fabric-ca-server start -b $TLSCA_UN:$TLSCA_PW'

Any suggestions on how I could do this correctly with yq?

1 Answers

The fix is quite trivial. In mikefarah/yq the write syntax takes the form

yq write [yaml_file] [path_expression] [value] [flags]

You were right in identifying the path_expression, but just didn't include the right quotes to wrap the replacement text. In most shells (including bash) wrapping stuff over double quotes preserves the literal value of the string (except embedded double quotes). So you just need to do

yq w docker-compose.yaml fabric-ca-server.command "sh -c 'fabric-ca-server start -b admin:adminpw'"

Once you confirm the replacement text is as "expected", add the -i tag to make the file change permanent.

Related