Extracting variable in YAML from a shell script
I'd recommend using a proper parser such as yq. Your task (last value of last element of acceleration_matrix
) then becomes as simple as
yq eval '.acceleration_matrix[-1][-1]' nastran_acceleration_matrix.yml
How can I parse a YAML file from a Linux shell script?
My use case may or may not be quite the same as what this original post was asking, but it's definitely similar.
I need to pull in some YAML as bash variables. The YAML will never be more than one level deep.
YAML looks like so:
KEY: value
ANOTHER_KEY: another_value
OH_MY_SO_MANY_KEYS: yet_another_value
LAST_KEY: last_value
Output like-a dis:
KEY="value"
ANOTHER_KEY="another_value"
OH_MY_SO_MANY_KEYS="yet_another_value"
LAST_KEY="last_value"
I achieved the output with this line:
sed -e 's/:[^:\/\/]/="/g;s/$/"/g;s/ *=/=/g' file.yaml > file.sh
s/:[^:\/\/]/="/g
finds:
and replaces it with="
, while ignoring://
(for URLs)s/$/"/g
appends"
to the end of each lines/ *=/=/g
removes all spaces before=
Extract yaml file from a variable within a yaml file
I can't replicate your code exactly, but here's what I'm getting (OSX, bash v4.4.23, yq v2.1.0):
var=$(cat test.yaml | yq r - data.helm_values)
echo "$var"
with output
# replicas: number of pods
replicas: 1
# test
hello: world
If I forget the quotes, (echo $var
), then:
# replicas: number of pods replicas: 1 # test hello: world
(no line breaks, no \n
).
I can even further process it:
echo "$var" | yq r - hello
# => world
With yq v2.6.0 the command arguments have changed:
var=$(cat test.yaml | yq -r .data.helm_values)
echo "$var"
Linux shell get value of a field from a yml file
That is fairly easy, not using sed
, but with appropriate shell tools. First, if you need to preserve sample
in a variable for later use, then something like the following will work using bash substring replacement to isolate sample
on the Test:/database: line:
$ db=$(grep -A3 'test:' database.yml | tail -n1); db=${db//*database: /}; echo "$db"
sample
or for a shorter solution that you can dump to the command line, remove the variable and command substitution and use a tool like cut
:
$ grep -A3 'test:' database.yml | tail -n1 | cut -c 13-
sample
or, with awk
, simply:
$ grep -A3 'test:' database.yml | tail -n1 | awk '{ print $2}'
sample
All of the different ways can be used inside command substitution (i.e. var=$(stuff)
) to store sample
in var
, it is just a matter of which you would rather use. I think you get the idea.
How to read a specific data from a yaml file inside a shell script
Here's an example with yq. All of the following assumes that the values do not contain newlines.
Given
$ cat test.yaml
---
test:
config:
abc: name1
xyz: name2
then
yq e '.test.config | to_entries | map(.value) | .[]' test.yaml
outputs
name1
name2
You can read them into variables like
{ read -r var1; read -r var2; } < <(yq e '.test.config | to_entries | map(.value) | .[]' test.yaml)
declare -p var1 var2
declare -- var1="name1"
declare -- var2="name2"
I would read them into an associative array with the yaml key though:
declare -A conf
while IFS="=" read -r key value; do conf["$key"]=$value; done < <(
yq e '.test.config | to_entries | map([.key, .value] | join("=")) | .[]' test.yaml
)
declare -p conf
declare -A conf=([abc]="name1" [xyz]="name2" )
Then you can write
echo "test config for abc is ${conf[abc]}"
# or
for var in "${!conf[@]}"; do printf "key %s, value %s\n" "$var" "${conf[$var]}"; done
I'm using "the Go implementation"
$ yq --version
yq (https://github.com/mikefarah/yq/) version 4.16.1
Get variables from a a file in bash
Consider using source
, which will load the variables from that file
#!/bin/bash
source "$1"
echo "$database"
# mydb
echo "$table"
# mytable
echo "$partitons"
# p1,p2,p3
For more information about source
see this superuser-question
Get value from yaml array in bash
This won't work in all systems, but
sed -n '/name: "kube-admin-local"/,/name:/s/.*client-certificate-data: \(.*\)/\1/p'
Should do it.
-n
: don't print unless explicitly stated/name: "kube-admin-local"/,/name:/
: lines between those matches- rest : substitute data and print
Extract from YAML values dynamically
YAML is not a programming language. It doesn't let you extract anything and it doesn't let you send anything, because it does not provide you with any kind of actions or processing instructions.
While you can reference nodes multiple times with anchors, that doesn't help you here because you would need to concatenate values, which is not something that is possible in YAML. A solution that would work looks like this (shortened for clarity):
map:
&a FirstBin:
source: value-field
field-name: ServiceID
&b SecondBin:
source: value-field
field-name: ServiceID
shouldDeleteOnNull: [*a, *b]
As you can see, I needed to make shouldDeleteOnNull
a sequence rather than a scalar to make this work. This does not seem like much of an improvement.
Anything more sophisticated would need to be implemented in the code loading the file and therefore does not make sense to be discussed in a pure YAML context.
Extract each line using shell script and assign it to variables and save it individually as new file
This script is an example to read and parse the file (I called the data file "data.txt"):
#!/bin/sh
IFS=,
# read lines like: xxxxx,2017-06-26 13:12:53.750,-9.5949,124.6654,23.29,xxxx,yyyyy,mb,5.0,
while read xxx1 datetime lat long dep xxx2 xxx3 xxx4 mag; do
# input lines are partly split
echo "Read $datetime"
echo "lat=$lat long=$long dep=$dep"
# parse datetime field which is like 2017-06-26 13:12:53.750
date=$(echo $datetime |cut -d" " -f1) # -d tells the field separator
time=$(echo $datetime |cut -d" " -f2) # -f tells the field number to extract
echo "date=$date time=$time"
# extract year value from date, which is like 2017-06-26
year=$(echo $date |cut -d"-" -f1)
echo "year=$year"
# go on this way to fill up all the variables...
# ...left as an exercize...!
# after this comment, down until the "done" keyword,...
# ...you will have all the variables set, ready to be processed
done <data.txt
When this script is run, it shows the following:
user@machine:/tmp$ ./script.sh
Read 2017-06-26 13:12:53.750
lat=-9.5949 long=124.6654 dep=23.29
date=2017-06-26 time=13:12:53.750
year=2017
Read 2017-06-24 07:27:07.700
...
user@machine:/tmp$
As noted in some comment, read about the read command and cut(1) command. Hope it helps.
Related Topics
Allocating a Data Page in Linux with Nx Bit Turned Off
How to Get Around the Linux "Too Many Arguments" Limit
Perf_Event_Open Always Returns -1
Ada Program Works in Linux But Not in Gps Windows 10
When Running Ls -L, Why Does the Filesize on a Directory Not Match the Output of Du
Raspberry Pi Refusing Connection to Bottle Server
File Glob Patterns in Linux Terminal
Linux Randomly Deleted My File While Compiling What Do I Do
Docker-Compose Stop Working After Docker Desktop Installation on Debian 11
How to Use the Parallel Command to Exploit Multi-Core Parallelism on My MACbook
G++ Always Fails with Undefined Reference to _Unwind_Getipinfo
Why Would the Elf Header of a Shared Library Specify Linux as the Osabi
Gatttool Non-Interactive Mode --Char-Write
Delete Files with Backslash in Linux
Rust Linux Version Glibc Not Found - Compile for Different Glibc/Libc6 Version