Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I do string concatenation, or string replacement in YAML?

I have this:

user_dir: /home/user
user_pics: /home/user/pics

How could I use the user_dir for user_pics? If I have to specify other properties like this, it would not be very DRY.

like image 300
Geo Avatar asked Mar 30 '11 08:03

Geo


People also ask

Can you concatenate strings in Yaml?

Concatenating strings and/or variablesThe standard YAML format does not support the notion of string concatenation. Since concatenating string values is a common pattern in easyconfig files, the EasyBuild framework defines the ! join operator to support this.

What are the 2 methods used for string concatenation?

There are two ways to concatenate strings in Java: By + (String concatenation) operator. By concat() method.

How do I append a string to another string?

Concatenation is the process of appending one string to the end of another string. You concatenate strings by using the + operator. For string literals and string constants, concatenation occurs at compile time; no run-time concatenation occurs. For string variables, concatenation occurs only at run time.


4 Answers

You can use a repeated node, like this:

user_dir: &user_home /home/user user_pics: *user_home 

I don't think you can concatenate though, so this wouldn't work:

user_dir: &user_home /home/user user_pics: *user_home/pics 
like image 166
Brian Wells Avatar answered Sep 20 '22 11:09

Brian Wells


It's surprising, since the purpose of YAML anchors & references is to factor duplication out of YAML data files, that there isn't a built-in way to concatenate strings using references. Your use case of building up a path name from parts is a good example -- there must be many such uses.

Fortunately there's a simple way to add string concatenation to YAML via custom tags in Python.

import yaml  ## define custom tag handler def join(loader, node):     seq = loader.construct_sequence(node)     return ''.join([str(i) for i in seq])  ## register the tag handler yaml.add_constructor('!join', join)  ## using your sample data yaml.load(""" user_dir: &DIR /home/user user_pics: !join [*DIR, /pics] """) 

Which results in:

{'user_dir': '/home/user', 'user_pics': '/home/user/pics'} 

You can add more items to the array, like " " or "-", if the strings should be delimited.

like image 23
Chris Johnson Avatar answered Sep 20 '22 11:09

Chris Johnson


If you are using python with PyYaml, joining strings is possible within the YAML file. Unfortunately this is only a python solution, not a universal one:

with os.path.join:

user_dir: &home /home/user
user_pics: !!python/object/apply:os.path.join [*home, pics]

with string.join (for completeness sake - this method has the flexibility to be used for multiple forms of string joining:

user_dir: &home /home/user
user_pics: !!python/object/apply:string.join [[*home, pics], /]
like image 30
user2502636 Avatar answered Sep 19 '22 11:09

user2502636


I would use an array, then join the string together with the current OS Separator Symbol

like this:

default: &default_path "you should not use paths in config"
pictures:
  - *default_path
  - pics
like image 25
Adam Avatar answered Sep 19 '22 11:09

Adam