Issue
I have a yaml file where i need to copy a key:value (when: var) to the task underneath and need to repeat that for each block.
How it looks like now:
- set_fact: something
- set_fact: var_a
- task: do the foo
when: var_a
- task: do the goo
- set_fact: something
- set_fact: var_b
- task: do the fofo
when: var_b
- task: do the gogp
- set_fact: something
- set_fact: var_c
- task: do the fooolo
when: var_c
- task: do the gooolo
How i need it to look like:
- set_fact: something
- set_fact: var_a
- task: do the foo
when: var_a
- task: do the goo
when: var_a
- set_fact: something
- set_fact: var_b
- task: do the fofo
when: var_b
- task: do the gogp
when: var_b
- set_fact: something
- set_fact: var_c
- task: do the fooolo
when: var_c
- task: do the gooolo
when: var_c
From researching how to do this, i think a vim loop could do that but i have no clue how to do that. In case anybody has any hints, i'd be very grateful.
Edit: What i tried. With this i captured the values i needed. (the var_ values)
grep -e set_fact -B1 filterlist_playbook.yml|grep -e "^.*\:"|grep -v "set\_fact\:"|awk -F":" '{print $1}'
I tried this in two different ways.
1 first add the "when:" field and then copy/paste the var_ value Adding the when: field was ok with sed. Pasting the right value sequentially... i do not find info how to do that, my colleagues also do not know.
2 copy/paste the "when: var_" value to the block underneath. Again capturing the right value is ok with sed, pasting it sequentially leaves me scratching my head and googling into oblivion.
Note: I will definitely select a working answer but its taking me time to try each one of them.
Solution
Here is how I would do it in Vim:
:g/when/normal mzvip^[:'zt'>^M
with ^[
obtained with <C-v><Esc>
and ^M
obtained with <C-v><CR>
.
Breakdown:
:g/<pattern>/<command>
executes<command>
on every line that matches<pattern>
.:normal xxx
executes normal commands from command-line mode.mz
puts mark'z
on the matched line.vip
visually selects the current paragraph, placing mark'>
on its last line.<Esc>
leaves visual mode.:'zt'>
copies line with mark'z
below line with mark'>
.<CR>
executes that last command.
See :help :global
, :help :normal
, :help mark-motions
, :h :t
, and :h :range
.
Note that, intuitively, using mark '}
like this:
:g/when/t'}
looks like it would solve the problem neatly, but Vim puts mark '}
on the first blank line after an actual paragraph, which doesn't help us since our anchor is the last line of the actual paragraph.
That is one of the reasons why the vip
dance is necessary: we need a mark on the last line of the paragraph, not after it, and visually selecting the "inner paragraph" does just that with mark '>
.
Answered By - romainl Answer Checked By - Pedro (WPSolving Volunteer)