|
|
@@ -0,0 +1,97 @@ |
|
|
Found [here](http://stackoverflow.com/questions/5014632/how-can-i-parse-a-yaml-file-from-a-linux-shell-script/21189044#21189044) by [Stephan Farestam](http://stackoverflow.com/users/1792684/stefan-farestam) |
|
|
|
|
|
Here is a bash-only YAML parser that leverages sed and awk to parse simple yaml files: |
|
|
|
|
|
function parse_yaml { |
|
|
local prefix=$2 |
|
|
local s='[[:space:]]*' w='[a-zA-Z0-9_]*' fs=$(echo @|tr @ '\034') |
|
|
sed -ne "s|^\($s\):|\1|" \ |
|
|
-e "s|^\($s\)\($w\)$s:$s[\"']\(.*\)[\"']$s\$|\1$fs\2$fs\3|p" \ |
|
|
-e "s|^\($s\)\($w\)$s:$s\(.*\)$s\$|\1$fs\2$fs\3|p" $1 | |
|
|
awk -F$fs '{ |
|
|
indent = length($1)/2; |
|
|
vname[indent] = $2; |
|
|
for (i in vname) {if (i > indent) {delete vname[i]}} |
|
|
if (length($3) > 0) { |
|
|
vn=""; for (i=0; i<indent; i++) {vn=(vn)(vname[i])("_")} |
|
|
printf("%s%s%s=\"%s\"\n", "'$prefix'",vn, $2, $3); |
|
|
} |
|
|
}' |
|
|
} |
|
|
|
|
|
It understands files such as: |
|
|
|
|
|
## global definitions |
|
|
global: |
|
|
debug: yes |
|
|
verbose: no |
|
|
debugging: |
|
|
detailed: no |
|
|
header: "debugging started" |
|
|
|
|
|
## output |
|
|
output: |
|
|
file: "yes" |
|
|
|
|
|
|
|
|
Which, when parsed using: |
|
|
|
|
|
parse_yaml sample.yml |
|
|
|
|
|
will output: |
|
|
|
|
|
global_debug="yes" |
|
|
global_verbose="no" |
|
|
global_debugging_detailed="no" |
|
|
global_debugging_header="debugging started" |
|
|
output_file="yes" |
|
|
|
|
|
it also understands yaml files, generated by ruby which may include ruby symbols, like: |
|
|
|
|
|
--- |
|
|
:global: |
|
|
:debug: 'yes' |
|
|
:verbose: 'no' |
|
|
:debugging: |
|
|
:detailed: 'no' |
|
|
:header: debugging started |
|
|
:output: 'yes' |
|
|
|
|
|
and will output the same as in the previous example. |
|
|
|
|
|
typical use within a script is: |
|
|
|
|
|
eval $(parse_yaml sample.yml) |
|
|
|
|
|
parse_yaml accepts a prefix argument so that imported settings all have a common prefix (which will reduce the risk of namespace collisions). |
|
|
|
|
|
parse_yaml sample.yml "CONF_" |
|
|
|
|
|
yields: |
|
|
|
|
|
CONF_global_debug="yes" |
|
|
CONF_global_verbose="no" |
|
|
CONF_global_debugging_detailed="no" |
|
|
CONF_global_debugging_header="debugging started" |
|
|
CONF_output_file="yes" |
|
|
|
|
|
Note that previous settings in a file can be referred to by later settings: |
|
|
|
|
|
## global definitions |
|
|
global: |
|
|
debug: yes |
|
|
verbose: no |
|
|
debugging: |
|
|
detailed: no |
|
|
header: "debugging started" |
|
|
|
|
|
## output |
|
|
output: |
|
|
debug: $global_debug |
|
|
|
|
|
Another nice usage is to first parse a defaults file and then the user settings, which works since the latter settings overrides the first ones: |
|
|
|
|
|
eval $(parse_yaml defaults.yml) |
|
|
eval $(parse_yaml project.yml) |
|
|
|
|
|
|