ephemeric has asked for the wisdom of the Perl Monks concerning the following question:

Hi, I would like to append a parameter "transparent_hugepage=never" to the below regex matched line in-between the quotes. On subsequent runs the substitution should be ignored to maintain idempotence (run as an Ansible playbook task). I tried a few things but failed as my knowledge is very limited. Thank you for your help and pardon my poor articulation. Line in question:

GRUB_CMDLINE_LINUX="crashkernel=auto rd.lvm.lv=centos/root rd.lvm.lv=centos/swap rhgb quiet"

The sed keeps appending after repeating the play as I can't get the negative lookahead assertion to work, I think that's what it is?

sed '/^GRUB_CMDLINE_LINUX=.*/ s/\(.*\)"/\1 transparent_hugepage=never"/' $line

And this from the playbook appends after the last quote breaking the config:

+ replace: + backup: yes + dest: /etc/default/grub + regexp: '(^GRUB_CMDLINE_LINUX(?!.*\btransparent_hugepage=never\b).*)$' + replace: '\1 transparent_hugepage=never"'

Replies are listed 'Best First'.
Re: GRUB Append Parameter in-between Quotes
by shmem (Chancellor) on Sep 09, 2016 at 18:48 UTC
    The sed keeps appending after repeating the play as I can't get the negative lookahead assertion to work, I think that's what it is?

    Maybe that's what it is, and maybe it is because sed doesn't implement it. TIMTOWTDI also applies to sed:

    sed '/^GRUB_CMDLINE_LINUX=.*/ { /transparent_hugepage/! s/\(.*\)"/\1 t +ransparent_hugepage=never"/}' $line

    Using perl, things might be easier.

    perl -le'print map{pack c,($-++?1:13)+ord}split//,ESEL'

      Nice job ++. I took a crack at this with sed and perl this afternoon, but was cut short due to a meeting.

      Thank you so much, works! How would one do this in Perl?

Re: GRUB Append Parameter in-between Quotes
by neilwatson (Priest) on Sep 09, 2016 at 18:48 UTC

      I'm sorry, should have said that I can't get it to work in sed and Ansible module, how would one go about doing it in Perl?

        See perlrun for -p and -e:

        echo 'FOO="bar"' | perl -pe '/^FOO=/ and s/"$/ baz"/;'
Re: GRUB Append Parameter in-between Quotes
by haukex (Archbishop) on Sep 13, 2016 at 15:36 UTC

    Hi ephemeric,

    A little late but here's a try with Perl. This is like hippo's solution but it adds the detection of whether the parameter has already been added or not. Personally I don't mind breaking up regexes into several regexes if it helps in thinking about the solution.

    perl -pe 's/"\s*$/ transparent_hugepage=never"/ if /^GRUB_CMDLINE_LINU +X=/ && !/transparent_hugepage/' filename

    Hope this helps,
    -- Hauke D

      Thank you.