1

Using a bash script, I am trying to edit a Magento 2 env.php config file. The bash script first performs some other operations. It needs to change this part in the config file on line 11-14:

  'session' => 
  array (
    'save' => 'files',
  ),

Into this:

'session' => 
   array (
   'save' => 'redis',
   'redis' => 
      array (
        'host' => '127.0.0.1',
        'port' => '6379',
        'password' => '',
        'timeout' => '2.5',
        'persistent_identifier' => '',
        'database' => '0',
        'compression_threshold' => '2048',
        'compression_library' => 'gzip',
        'log_level' => '1',
        'max_concurrency' => '6',
        'break_after_frontend' => '5',
        'break_after_adminhtml' => '30',
        'first_lifetime' => '600',
        'bot_first_lifetime' => '60',
        'bot_lifetime' => '7200',
        'disable_locking' => '0',
        'min_lifetime' => '60',
        'max_lifetime' => '2592000'
    )
  ),
'cache' =>
array(
   'frontend' =>
   array(
      'default' =>
      array(
         'backend' => 'Cm_Cache_Backend_Redis',
         'backend_options' =>
         array(
            'server' => '127.0.0.1',
            'database' => '0',
            'port' => '6379'
            ),
    ),
    'page_cache' =>
    array(
      'backend' => 'Cm_Cache_Backend_Redis',
      'backend_options' =>
       array(
         'server' => '127.0.0.1',
         'port' => '6379',
         'database' => '1',
         'compress_data' => '0'
       )
    )
  )
),

I have tried to achieve using various ways with both sed and awk and already spent multiple hours on it, but I cannot figure out what I am doing wrong. I had no prior experience with both sed, awk or shell scripts in general. After I couldn't achieve what I really wanted, a "search and replace" which you can do in every GUI text editor, I ended up deleting the old contents of 'session' with sed by referencing the line numbers and trying to add the right contents using awk. I already tried using backslashes at the end of every sentence. This is the script I wrote with both sed and awk, after first trying to get this right using:

sed -i -e 12d -e 13d -e 14d /var/www/ecom/app/etc/env.php
awk '
{ print }
/  'session' => / {
print "  array ( "
print "  'save' => 'redis',"
print "  'redis' =>"
print "     array ("
print "       'host' => '127.0.0.1',"
print "       'port' => '6379',"
print "       'password' => '',"
print "       'timeout' => '2.5',"
print "       'persistent_identifier' => '',"
print "       'database' => '0',"
print "       'compression_threshold' => '2048',"
print "       'compression_library' => 'gzip',"
print "       'log_level' => '1',"
print "       'max_concurrency' => '6',"
print "       'break_after_frontend' => '5',"
print "       'break_after_adminhtml' => '30',"
print "       'first_lifetime' => '600',"
print "       'bot_first_lifetime' => '60',"
print "       'bot_lifetime' => '7200',"
print "       'disable_locking' => '0',"
print "       'min_lifetime' => '60',"
print "       'max_lifetime' => '2592000'"
print "   )"
print " ),"' /var/www/html/app/etc/env.php

However, the result I get is:

awk: cmd. line:27: print " ), "
awk: cmd. line:27:             ^ unexpected newline or end of string

My guess is that I am not exiting properly, but numerous Google searches haven't resulted in finding a solution.

This is another attempt using cat and sed, it doesn't work either and results in an empty file:

cat <<EOF <(sed -i '1,/  'session' => \n  array (\n    'save' => 'files',\n  ),/d' /var/www/html/app/etc/env.php) >> /var/www/html/app/etc/env.php
'session' =>
   array (
   'save' => 'redis',
   'redis' =>
      array (
        'host' => '127.0.0.1',
        'port' => '6379',
        'password' => '',
        'timeout' => '2.5',
        'persistent_identifier' => '',
        'database' => '0',
        'compression_threshold' => '2048',
        'compression_library' => 'gzip',
        'log_level' => '1',
        'max_concurrency' => '6',
        'break_after_frontend' => '5',
        'break_after_adminhtml' => '30',
        'first_lifetime' => '600',
        'bot_first_lifetime' => '60',
        'bot_lifetime' => '7200',
        'disable_locking' => '0',
        'min_lifetime' => '60',
        'max_lifetime' => '2592000'
    )
  ),
'cache' =>
array(
   'frontend' =>
   array(
      'default' =>
      array(
         'backend' => 'Cm_Cache_Backend_Redis',
         'backend_options' =>
         array(
            'server' => '127.0.0.1',
            'port' => '6379'
            ),
    ),
    'page_cache' =>
    array(
      'backend' => 'Cm_Cache_Backend_Redis',
      'backend_options' =>
       array(
         'server' => '127.0.0.1',
         'port' => '6379',
         'database' => '1',
         'compress_data' => '0'
       )
    )
  )
),
EOF

I also made some other attempts at solving this problem I am facing using only sed, but unfortunately I didn't save those, however, they didn't work either.

Does anybody know how I could solve this?

Edit: I am trying to perform this editing on Debian 9 "Stretch"

EDIT 2: Based on feedback I received here, I have rephrased the question here: Find and replace multiple lines of text from command line

Community
  • 1
  • 1
phol
  • 85
  • 8
  • Welcome to Stack Overflow. And congratulations on your first question. Maybe what you're trying to do is http://stackoverflow.com/questions/16715373/insert-contents-of-a-file-after-specific-pattern-match – ashawley May 08 '17 at 04:16

2 Answers2

1
awk '
NR==FNR { new = new $0 ORS; next }
FNR==11 { printf "%s", new; f=1 }
!f
FNR==14 { f=0 }
' replacement.txt magento.php
Ed Morton
  • 188,023
  • 17
  • 78
  • 185
  • @TobySpeight no, as always you are utterly wrong. I see in your last 12 answers you've only had 1 accepted - maybe if you focus more on **your** answers and less on other peoples you'll be able to contribute more to the site? – Ed Morton May 08 '17 at 14:17
  • Thanks for your answer. Although I'd rather use a search function to replace the block of text I want to replace, this solution does seem to work. By doing this: awk ' NR==FNR { new = new $0 ORS; next } FNR==11 { printf "%s", new; f=1 } !f FNR==14 { f=0 } ' replacement.txt oldfile.php > newfile.php I am able to save it, however, if I use as a last line this: ' replacement.txt oldfile.php > oldfile.php To edit directly instead of writing to a new file, it results in an empty file. It's probably very simple, but would you know how to solve this? – phol May 08 '17 at 14:36
  • `I'd rather use a search function to replace the block of text I want to replace` - that's easily do-able but then you really threw us a red herring by telling us the line numbers you want replaced. Why did you do that if you wanted to do the replacement based on matching a string rather than line numbers? Right, UNIX commands print their output to stdout and if you want to redirect stdout to a file then you do so with `>`. – Ed Morton May 08 '17 at 14:40
  • Well, I should have been clearer probably, sorry about that. This was what I tried after struggling to do it using a search function for two hours. The last code block in my post was an attempt to use search and replace but it doesn't work unfortunately. – phol May 08 '17 at 14:41
  • There are no UNIX commands that edit files directly, they all use a temp file. The only question is do you want to know the temp file name or not? In GNU sed you can use `-i` without specifying the temp file name and in GNU awk you can use `-i inplace` to do the same. With **any** UNIX command, though, you can simply do `cmd file > tmp && mv tmp file` (where `cmd` is sed/grep/tail/awk/whatever) and it does exactly the same thing that `sed -i` or `awk -i inplace` or `perl -i` does behind the scenes. – Ed Morton May 08 '17 at 14:42
  • Rather than trying to repair this question, accept this answer and post a new question but this time use a briefer replacement text block as it doesn't have to be 50 lines long to demonstrate your problem, and specify if white space matters in the string you're searching for. – Ed Morton May 08 '17 at 14:45
  • 1
    Thanks for your rapid reply. I will try to incorporate that change! – phol May 08 '17 at 14:45
  • I have posted a new and rephrased question.: http://stackoverflow.com/questions/43851572/find-and-replace-text-from-command-line – phol May 08 '17 at 15:29
1

If you can use GNU sed, you could put your text in a file and replace the offending lines with the r command. If you can not, you need to fix your quoting. Or, you could use something like:

{ sed 11q old_file; cat replacement_text; sed 1,14d old_file; } > new_file
Michael Vehrs
  • 3,293
  • 11
  • 10