Demmy
Demmy

Reputation: 25

Regex: match strings in separated lines

community, how can I match the name and executor lines using regex under the section called [[runners]]

I was playing with things such as:

(?=.*?(name.*))(?=.*?(executor.*))

(?<=\[runners\])[\s\S](\s*name.*)

/(?<=\[\[runners\]\])[\s\S](?=.*?(name.*))(?<=[\s\S])(?=.*?(executor.*))/g

File example:

[[runners]]
  name = "admin"
  url = "url"
  token = "token"
  executor = "shell"
  [runners.custom_build_dir]
  [runners.cache]
    [runners.cache.s3]
    [runners.cache.gcs]
    [runners.cache.azure]

[[runners]]
  name = "admin2"
  url = "url"
  token = "token"
  executor = "docker"
  [runners.custom_build_dir]
  [runners.cache]
    [runners.cache.s3]
    [runners.cache.gcs]
    [runners.cache.azure]

Expected result:

[[runners]]  
name = "admin"
executor = "shell"
[[runners]]
name = "admin2"
executor = "docker"

update: based on @PoulBak comment the final solution for me is

grep -E '\[\[runners\]\]|name = "[^"]+"|executor = "[^"]+"' /etc/gitlab-runner/config.toml

Upvotes: 0

Views: 51

Answers (1)

Diego D
Diego D

Reputation: 8153

I made a demo using javascript as the regex performer.

My strategy was splitting the input string using double newline as separator with this statement:

data.split(/\n\n/img);

And then for each runner element returned above, use two different regex to fetch the properties name and executor.

The output will contain the string [[runners]] for any runner found in the input, but the properties name or executor will be listed only if existing in the input for the corresponding runner.

For this task a proper parser would be more appropriate because you could just have a cursor moving to the next line and keeping state of what's going on. Anyway I did my best to contain performance drawing for this task while using regex anywhere possible.

const data = `
[[runners]]
  name = "admin"
  url = "url"
  token = "token"
  executor = "shell"
  [runners.custom_build_dir]
  [runners.cache]
    [runners.cache.s3]
    [runners.cache.gcs]
    [runners.cache.azure]

[[runners]]
  name = "admin2"
  url = "url"
  token = "token"
  executor = "docker"
  [runners.custom_build_dir]
  [runners.cache]
    [runners.cache.s3]
    [runners.cache.gcs]
    [runners.cache.azure]

[[runners]]  
  url = "runnerWithNoName"
  token = "token"
  executor = "docker"
  [runners.custom_build_dir]
  [runners.cache]
    [runners.cache.s3]
    [runners.cache.gcs]
    [runners.cache.azure]  
`;

let output = '';

const runners = data.split(/\n\n/img);
for(let runner of runners){  
  const name = /\s*name = "([^"]*)"/.exec(runner);
  const executor = /\s*executor = "([^"]*)"/.exec(runner);  

  output += "[[runners]]\n";
  if(name !== null) output += name[0].trim() + "\n";
  if(executor !== null) output += executor[0].trim() + "\n";  
}

console.log(output);

Upvotes: 1

Related Questions