Reputation: 2980
I have a database.yml file like
development:
adapter: mysql2
encoding: utf8
database: d360
host: localhost
username: root
password: password
test:
adapter: mysql2
encoding: utf8
database: sample
host: localhost
username: root
password: password
Now, I want value of database of test environment (that is sample
for the YAML shown).
How can we do that using sed?
Upvotes: 44
Views: 75542
Reputation: 132778
There are better tools than sed
. You might be stuck on a minimal system, but other people looking for an answer probably won't be.
The python version of yq acts like jq:
$ pip3 install yq
$ yq -r .test.database database.yml
sample
shyaml works too, but has an odd restriction that you can only redirect into it:
$ pip3 install shyaml
$ shyaml get-value test.database < database.yml
sample
If perl
is around and you have YAML installed:
$ cpan YAML
$ perl -MYAML -le 'print YAML::LoadFile(shift)->{test}{database}' database.yml
sample
Or, if you want ruby
:
$ ruby -r yaml -e 'puts YAML.load_file(ARGV[0])["test"]["database"]' database.yml
sample
Upvotes: 33
Reputation: 676
On Ubuntu, install yq
:
$ sudo apt update
$ sudo apt install snapd
$ sudo snap install yq
Use yq
:
$ value=$(yq r database.yml test.database)`
Upvotes: 14
Reputation: 5390
For macOS / Linux users using Homebrew, yq
is available, and provides a jq
-like expeience:
$ brew install yq
$ yq eval .test.database database.yml
sample
Upvotes: 3
Reputation: 46826
YAML obviously isn't natively supported in shell. But sed also isn't a YAML parser. Neither are grep, tail, cut, etc. I'm pretty sure you'd need an actual language in which to write a proper parser. Awk, perl, python, erlang, etc.
You could use sed or shell or somesuch if you know that your YAML data will always be formatted in a certain way or hold certain values in a particular order, but to make a parser that will work generally, and on any ol' YAML file you point it at, you'll need to emulate the parsers that already exist in other languages.
If you don't want to write your own (perhaps asking the StackOverflow community for help once you have some code to consider), then one option might be to install a tool like shyaml which can accurately parse files and give you authoritative content. A quick solution easily implemented into your scripts, though it has some dependencies (python).
Upvotes: 8
Reputation: 84531
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.
Upvotes: 31