slist string_split report

21 views
Skip to first unread message

bofh...@gmail.com

unread,
Dec 22, 2016, 1:41:44 AM12/22/16
to help-cfengine
Not sure why this is happening.  How come the first report in "my_split" is blank?

#### Begin Promise
body common control
{
  bundlesequence => { "example" };
  inputs => { "$(sys.libdir)/stdlib.cf" };
}

bundle agent example
{
  vars:
     "my_list"    slist => { "xvnc10", "xvnc30", "xvnc40" };
     "my_split[$(my_list)]"  slist => string_split("$(my_list)", "xvnc", "99");

  reports:
    "my_list   $(my_list)";
    "my_split  $(my_split[$(my_list)])";
}
#### End Promise


Report:
R: my_list   xvnc10
R: my_list   xvnc30
R: my_list   xvnc40
R: my_split
R: my_split  10
R: my_split  30
R: my_split  40


Thank you in advance,
Robin Friedrich








Neil Watson

unread,
Dec 22, 2016, 9:08:58 AM12/22/16
to help-cfengine
Run the agent in verbose mode and see if the vars are evaluating on a
later run.

--
Neil H Watson @neil_h_watson
CFEngine reporting: https://github.com/neilhwatson/delta_reporting
CFEngine policy: https://github.com/neilhwatson/evolve_cfengine_freelib
CFEngine and vim: https://github.com/neilhwatson/vim_cf3

Nick Anderson

unread,
Dec 22, 2016, 9:46:28 AM12/22/16
to bofh...@gmail.com, help-cfengine

bofh...@gmail.com writes:

> Not sure why this is happening. How come the first report in "my_split" is
> blank?

When you split something you end up with at least 2 parts. In this case
your splitting off the front of a string, so you end up with an empty
element (the first part), and then the second part as another element.
Since your only interested in the second part you can use [[https://docs.cfengine.com/docs/3.10/reference-functions-nth.html][nth()]] to pick
it out.

#+BEGIN_SRC cfengine3 :exports both :wrap EXAMPLE
bundle agent main
{
vars:
"my_list" slist => { "xvnc10", "xvnc30", "xvnc40" };

# When you split a string, you will have at least 2 parts from splitting
# it. Since you are splitting off the front of the string you end up with
# an empty string (the first half of your split string) and then the digits
# in the second half. Since you are only interested in the second half of
# that split, you can pick it out using nth(). You might be able to do
# similar using data_regextract() or similar.

"my_split[$(my_list)]" string => nth( string_split( $(my_list), "^xvnc", 2), 1);

reports:
"CFEngine: $(sys.cf_version)";
"my_list $(my_list)";
"my_split $(my_split[$(my_list)])";
}
#+END_SRC

#+RESULTS:
#+BEGIN_EXAMPLE
R: CFEngine: 3.11.0a.334d1fc
R: my_list xvnc10
R: my_list xvnc30
R: my_list xvnc40
R: my_split 10
R: my_split 30
R: my_split 40
#+END_EXAMPLE

--
Nick Anderson
Doer of things, CFEngine

Ted Zlatanov

unread,
Dec 22, 2016, 11:28:01 AM12/22/16
to help-c...@googlegroups.com
On Wed, 21 Dec 2016 22:41:44 -0800 (PST) bofh...@gmail.com wrote:

b> Not sure why this is happening. How come the first report in "my_split" is
b> blank?

Here's an example of how to remove that blank string. The first one,
using filter(), removes all blank strings. Note it requires function
wrapping, a new feature.

The second uses mapdata() with jq to split and remove the first element
every time. You could also use jq to remove all blank strings, and you
could make the result a map instead of an array of arrays.

HTH
Ted

#+begin_src cfengine3
bundle agent main
{
methods:
"test";

vars:
"test_state" data => bundlestate(test);
"test_string" string => storejson(test_state);

reports:
"$(this.bundle): state of things = $(test_string)";
}

bundle agent test
{
vars:
"my_list" slist => { "xvnc10", "xvnc30", "xvnc40" };
"my_split[$(my_list)]" slist => filter("", string_split($(my_list), "xvnc", "99"),
"no", "yes", 99999);
"my_map" data => mapdata("json_pipe", concat("$(def.jq) ", '.[]|split("xvnc")|del(.[0])'), my_list);
}
#+end_src

Output:

#+begin_src text
R: main: state of things = {
"my_list": [
"xvnc10",
"xvnc30",
"xvnc40"
],
"my_map": [
[
"10"
],
[
"30"
],
[
"40"
]
],
"my_split[xvnc10]": [
"10"
],
"my_split[xvnc30]": [
"30"
],
"my_split[xvnc40]": [
"40"
]
}
#+end_src

Nick Anderson

unread,
Dec 22, 2016, 12:19:45 PM12/22/16
to help-c...@googlegroups.com

Ted Zlatanov writes:

> Here's an example of how to remove that blank string. The first one,
> using filter(), removes all blank strings. Note it requires function
> wrapping, a new feature.

Yep, I like Teds filter() version better than my nth() version.

bofh...@gmail.com

unread,
Dec 22, 2016, 7:30:19 PM12/22/16
to help-cfengine
Excellent information from everyone as always.

Thank you very much.
Robin Friedrich
Reply all
Reply to author
Forward
0 new messages