简体   繁体   中英

Find and replace multiple lines of text from command line

I am trying to edit a config file using a script that also performs other operations.

The script needs to find certain consecutive lines of text and remove these. In place it needs to paste a new configuration starting on the same line as where the old configuration was. In both the old and the new configuration, use of spaces matters.

in configfile.php, this block of text:

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

needs to be found and replaced with content I put in replacement.txt at the same location.

Based on answers to similar questions, one of the things I tried is this:

cat replacement.txt <(sed -i '1,/  'session' => \n  array (\n    'save' => 'files',\n  ),/d' configfile.php) > configfile.php

This results in an empty file.

cat replacement.txt <(sed -i '1,/  'session' => \n  array (\n    'save' => 'files',\n  ),/d' configfile.php) > newfile.php

This does the same as cat replacement.txt > newfile.php does and I want to edit a file, not create a new file.

Does anybody know what is wrong with my syntax and how I can fix it?

I've asked this question before here , but I didn't completely understand myself what I wanted, so it got a bit too elaborate and confusing. I use Debian Linux.

Edit based on comment:

The replacement.txt looks like this:

  'session' =>
     array (
     'save' => 'redis',
     'redis' =>
        array (
          'host' => '127.0.0.1',
          'other_variable' => 'other_setting',
        )
     )
  ),

It is already indented the way it should be and can be inserted as is. Use of awk or sed is both fine.

With GNU awk for multi-char RS:

$ cat tst.awk
BEGIN { RS="^$"; ORS="" }
ARGIND==1 { old = $0 }
ARGIND==2 { new = $0 }
ARGIND==3 {
    if ( start = index($0,old) ) {
        $0 = substr($0,1,start-1) new substr($0,start+length(old))
    }
    print
}

$ awk -f tst.awk target.txt replacement.txt configfile.php
  foo
  'session' =>
     array (
     'save' => 'redis',
     'redis' =>
        array (
          'host' => '127.0.0.1',
          'other_variable' => 'other_setting',
        )
     )
  ),
  bar

The above was run on these input files:

$ cat  target.txt
  'session' =>
  array (
    'save' => 'files',
  ),
$
$ cat replacement.txt
  'session' =>
     array (
     'save' => 'redis',
     'redis' =>
        array (
          'host' => '127.0.0.1',
          'other_variable' => 'other_setting',
        )
     )
  ),
$
$ cat configfile.php
  foo
  'session' =>
  array (
    'save' => 'files',
  ),
  bar
$

With other awks it'd be:

$ cat tst.awk
FNR==1 { ++argind }
argind==1 { old = (FNR>1 ? old RS : "") $0 }
argind==2 { new = (FNR>1 ? new RS : "") $0 }
argind==3 { rec = (FNR>1 ? rec RS : "") $0 }
END {
    if ( start = index(rec,old) ) {
        rec = substr(rec,1,start-1) new substr(rec,start+length(old))
    }
    print rec
}

$ awk -f tst.awk target.txt replacement.txt configfile.php
  foo
  'session' =>
     array (
     'save' => 'redis',
     'redis' =>
        array (
          'host' => '127.0.0.1',
          'other_variable' => 'other_setting',
        )
     )
  ),
  bar

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM