1

I need to uncomment and edit this line using sed:

root@host:~# cat $CONF | grep "pm\.max_requests"
;pm.max_requests = 500

Tried this, but nothing worked:

root@host:~# sed -i "s/^;?pm\.max_requests *= *[^ ]*/pm.max_requests = 512/" ${CONF}
root@host:~# sed -i "s/^\;?pm\.max_requests *= *[^ ]*/pm.max_requests = 512/" ${CONF}
root@host:~# sed -i "s/^(;)?pm\.max_requests *= *[^ ]*/pm.max_requests = 512/" ${CONF}
root@host:~# sed -i "s/^(;?)pm\.max_requests *= *[^ ]*/pm.max_requests = 512/" ${CONF}

Here's what did work:

root@host:~# sed -i "s/^;pm\.max_requests *= *[^ ]*/pm.max_requests = 512/" ${CONF}

Problem is, the command has to work even if a semicolon isn't there.

I know I can start with something like below, but I was hoping I can have it done all in one line.

sed -i "s/#;pm\.max_requests/pm.max_requests/g" ${CONF}

Checked if this is a duplicate, but all I could find was Removed semicolon from a line in php.ini using shell command

ᴍᴇʜᴏᴠ
  • 4,804
  • 4
  • 44
  • 57
  • 2
    POSIX BRE (the regex flavour used by `sed` by default) doesn't support `?` as a meta-character. It may support `\?` and it does support `\{0,1\}`, but you will probably want to use ERE instead by using the `-E` flag (modern GNU sed & BSD sed) or the `-r` flag (older GNU sed). Using the `*` quantifier would be another alternative since there would be no obvious harm in removing multiple existing `;` characters at the start of the line – Aaron Dec 16 '19 at 14:43
  • 1
    "Some implementations support `\?` and `\+` as an alternative syntax to `\{0,1\}` and `\{1,\}`, but `\?` and `\+` are not part of the POSIX standard." ([source](https://www.regular-expressions.info/posix.html)) – Aaron Dec 16 '19 at 14:44
  • See https://ideone.com/VYEbQq, use `sed -i -E "s/^;?pm\.max_requests *= *[^ ]*/pm.max_requests = 512/" file` – Wiktor Stribiżew Dec 16 '19 at 14:50

1 Answers1

3

sed by default uses the Basic Regular Expressions (BRE) regex flavour which does not parse ? as the "0 or 1" quantifier. Your commands fail as they try to match an inexistant literal ? character.

Your alternatives are the following :

  • some implementations support \? as the "0 or 1" quantifier, although it's not POSIXly defined

    sed -i "s/^;\?pm\.max_requests *= *[^ ]*/pm.max_requests = 512/" ${CONF}
    
  • you can use the equivalent \{0,1\} quantifier

    sed -i "s/^;\{0,1\}pm\.max_requests *= *[^ ]*/pm.max_requests = 512/" ${CONF}
    
  • You could use the * quantifier instead of ?, which would lead to possibly removing multiple consecutive ; characters

    sed -i "s/^;*pm\.max_requests *= *[^ ]*/pm.max_requests = 512/" ${CONF}
    
  • you can switch to the Extended Regular Expressions (ERE) regex flavour, using sed -E for BSD sed or modern GNU sed and sed -r for older GNU sed. With this flavour, the ? quantifier will work as you expected it to.

    sed -iE "s/^;?pm\.max_requests *= *[^ ]*/pm.max_requests = 512/" ${CONF}
    
Benjamin Loison
  • 3,782
  • 4
  • 16
  • 33
Aaron
  • 24,009
  • 2
  • 33
  • 57