I'm trying grep 7 lines after match and replace a context in those 7 lines and save it in the same file.

For Example:

<IfModule prefork.c>
StartServers       8
MinSpareServers    5
MaxSpareServers   20
ServerLimit      256
MaxClients       256
MaxRequestsPerChild  4000

i would like to replace the value of MaxRequestsPerChild with 5000.

I have tried with:

grep "IfModule prefork.c" httpd.conf -A7 | /bin/sed -nE "/\bMaxRequestsPerChild\b/ s/[0-9]+/50/"

But no luck.

  • why not just grep for the string you're looking for in the first place?
    – imabug
    Jun 21, 2018 at 9:25
  • 1
    Sorry if I'm a bit daft, but why not just change the line in an editor?
    – Kusalananda
    Jun 21, 2018 at 9:25
  • @imabug there are other modules having the same pattern.
    – user296444
    Jun 21, 2018 at 9:26
  • 2
    there is several problem here, first, you want to edit a file and you do not provide sed with a file name but with stdin. So sed will never work, I suggest you write a script that get line number with grep and then sed inline at the properline number. I will not help you make this logic a oneliner
    – Kiwy
    Jun 21, 2018 at 9:28
  • 2
    @nkmoxk You're administrating 73 machines. Are you thinking you would run this over SSH in a loop? Have you considered Ansible?
    – Kusalananda
    Jun 21, 2018 at 9:30

3 Answers 3


Here is a SED solution.

sed '/<IfModule prefork.c>/,/MaxRequestsPerChild/s/MaxRequestsPerChild.*/MaxRequestsPerChild 5000/' apacheconf

It works by matching the Module name then replacing the next "MaxRequestsPerChild" line with the 5000 value. It will ignore the "MaxRequestsPerChild" of all other modules.


With GNU sed (not sure if syntax/feature is okay for other versions)

To change within 6 lines after matching line:

sed -E '/IfModule prefork\.c/{N;N;N;N;N;N;s/(MaxRequestsPerChild +)[0-9]+/\15000/}'

here, N will add a newline to the pattern space, then append the next line of input to the pattern space

If it is always 6th line:

sed -E '/IfModule prefork\.c/{n;n;n;n;n;n;s/[0-9]+/5000/}'

here n will replace the pattern space with the next line of input

Or, simpler syntax with relative addressing

sed -E '/IfModule prefork\.c/,+6 s/(MaxRequestsPerChild +)[0-9]+/\15000/'
  • Thanks, but not getting the result. Looks like problem with [0-9]+
    – user296444
    Jun 21, 2018 at 10:10
  • @nkmoxk can you give details.. did you get an error? or something else happened? it works for me on GNU sed(you've tagged linux, so I'm assuming you have GNU sed)
    – Sundeep
    Jun 21, 2018 at 10:24
  • its not replacing the value. if i remove + sign, it replaces only the first digit as expected.
    – user296444
    Jun 21, 2018 at 10:27
  • did you use sed -E ? may be your version needs sed -r?
    – Sundeep
    Jun 21, 2018 at 10:46

You could put sed's range operator , to good use here in case you are indifferent to line numbers:

sed -e '
   /<IfModule prefork.c>/,\|</IfModule>|!b
' config-file
  1. Store the range in the hold space.
  2. When the range end is detected, retrieve the range from the hold area, and
  3. Perform the desired substitution.
  4. Lines not falling in the range are left to themselves and passed on to stdout.
  • sed -e ' /<IfModule prefork.c>/,\|</IfModule>|!b H;\|</IfModule>|!d;g;s/.//; s/\(\(\n\)MaxRequestsPerChild[[:blank:]]\{1,\}\)[1-9][0-9]*\n/\15000\2/ ' httpd.conf | head -n108 | tail -n1 MaxRequestsPerChild 5000
    – user296444
    Jun 21, 2018 at 12:18
  • Thanks, but its not substituting.
    – user296444
    Jun 21, 2018 at 12:19
  • @nkmoxk You cannot write the sed command in one line as you've shown. Give each line of sed code with it's own -e option. Jun 22, 2018 at 5:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy