On Fri, 12 Feb 2016 16:50:37 +0100 Marco Marongiu <
bront...@gmail.com> wrote:
MM> I have a list of strings, [] I want to build a new list
MM> where each element [] will be the substring of the
MM> corresponding element [] from the beginning of the
MM> string and up to the first space
The below gives two solutions: first, we convert the slist into a data
container and use string_split() on its elements; and second, we join
the slist elements into a single string and use parsestringarray()
(noting that the single string must not exceed 4K and the slist elements
must be OK as classic array keys).
The proposed jq integration in
https://github.com/cfengine/core/pull/2319 will make this kind of work
trivial, but it's much more powerful than just list transformations.
Finally, the new regex_replace() function in 3.9 simplifies an aspect of
this specific case, and if you'll look at
https://dev.cfengine.com/issues/7346#note-14 I proposed a list version
of regex_replace() that would completely solve your problem. The only
reason I didn't create a new ticket is that I wasn't sure people would
find it useful. So if you'd like the list version of regex_replace(),
look at my comment and open a new ticket if you agree with it.
#+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:
"ntp_servers_slist"
"ntp_servers" data => mergedata(ntp_servers_slist);
"idx" slist => getindices(ntp_servers);
"collect_full_$(idx)" slist => string_split(nth("ntp_servers", $(idx)), " ", 2);
"collect[$(idx)]" string => nth("collect_full_$(idx)", 0);
"joined" string => join($(const.n), ntp_servers_slist);
"dim" int => parsestringarray(collect2, $(joined), "\s*#[^\n]*", " ", inf, inf);
"collect2_servers" slist => getindices(collect2);
}
#+end_src
Output:
#+begin_src text
% cf-agent -KI -f ~/sync/cf/test/
test_collect_substring.cf
R: main: state of things = {
"collect2[208.90.144.72][0]": "208.90.144.72",
"collect2[
bonehed.lcs.mit.edu][0]": "
bonehed.lcs.mit.edu",
"collect2[
bonehed.lcs.mit.edu][1]": "minpoll",
"collect2[
bonehed.lcs.mit.edu][2]": "9",
"collect2[
ntp1.conectiv.com][0]": "
ntp1.conectiv.com",
"collect2[
timekeeper.isi.edu][0]": "
timekeeper.isi.edu",
"collect2_servers": [
"
bonehed.lcs.mit.edu",
"
timekeeper.isi.edu",
"208.90.144.72",
"
ntp1.conectiv.com"
],
"collect[0]": "
ntp1.conectiv.com",
"collect[1]": "208.90.144.72",
"collect[2]": "
bonehed.lcs.mit.edu",
"collect[3]": "
timekeeper.isi.edu",
"collect_full_0": [
"
ntp1.conectiv.com"
],
"collect_full_1": [
"collect_full_2": [
"collect_full_3": [
"
timekeeper.isi.edu"
],
"dim": "4",
"idx": [
"0",
"1",
"2",
"3"
],
"joined": "
ntp1.conectiv.com\n208.90.144.72 #
ntp0.jrc.us\
nbonehed.lcs.mit.edu minpoll 9 # server seems to have a strong rate limiting\
ntimekeeper.isi.edu",
"ntp_servers": [
],
"ntp_servers_slist": [
]
}
#+end_src
MM> However, a reports promise containing $(data_split[$(ntp_servers)][0])
MM> never printed anything, while an assignment like this:
>> "server[$(ntp_servers)]"
>> string => "$(data_split[$(ntp_servers)][0])" ;
>>
MM> resulted in a segmentation fault (return code 139)
Can you please submit a bug on this?
Thanks
Ted