Bash заменить несколько строк в файле между двумя шаблонами содержимым другого файла?

Здесь вам может понадобиться одна из двух вещей.

  1. Использованиеteeдля получения результата echo, отправленного на терминал, а также в файл:

    $ echo 'hello!' | tee output
    hello!
    $ cat output
    hello!
    
  2. Использование scriptдля захвата всего терминального сеанса:

    $ script
    Script started, output file is typescript
    $ echo 'hello!' >output
    $ cat output
    hello!
    $ exit
    Script done, output file is typescript
    
    $ cat typescript
    Script started on Sat Nov 10 15:15:06 2018
    $ echo 'hello!' >output
    $ cat output
    hello!
    $ exit
    
    Script done on Sat Nov 10 15:15:37 2018
    

Если это не то, о чем вы просите, уточните свой вопрос.

0
12.01.2021, 17:24
2 ответа

Задачу можно решить множеством способов, некоторые из которых показаны ниже.

Примечание :/BEGIN/ /END/ Я выбрал так, чтобы они четко выделялись. Замените их необходимыми пограничными маркерами.

сед Предполагается, что /END/ не должно стоять в последней строке.

sed -e '
  /BEGIN/,/END/!b
  //!d;/END/!b
  r content.js
  N
' long.js

Рабочий:

  • печатать любую неблочную область как есть:/BEGIN/,/END/!b
  • Внутри блока удалить полость://!d
  • Печать верхней границы блока:/END/!b
  • Заполнить выходной буфер содержимым файла content.js.:r contents.jsЗдесь печать на стандартный вывод не выполняется.
  • Прочитайте следующую строку и добавьте к строке /END/. Акт чтения запускает очистку выходного буфера. Обратите внимание, что из-за команды N пространство шаблона не печатается в этом цикле. Это приводит к размещению содержимого файла content.js перед строкой /END/.

awk '
  BEGIN {
    repl = ARGV[1]
    ARGV[1] = ""
  }
  /BEGIN/ && !f {print;f=1}
  /END/ && f {
    while (getline t < repl > 0) {
      print t
    }
    f = 0
  }
  !f
' content.js long.js

perl -pe '
  $repl //= do{local $/;<STDIN>;};
  next unless my $e = /BEGIN/.../END/;
  $_ = $e =~ /E0/ ? $repl.$_
     : $e == 1 ? $_
     : s/.*//sr;
' long.js < content.js

contnt=$(< "content.js" sed -e 's/^/ /')

cat - <<eof | ed -s - long.js
1m1
/BEGIN/+1,/END/-1c
$contnt
.
?BEGIN?+1,/END/-1s/^ //
wq
eof
2
18.03.2021, 22:37

Я нашел способ использовать sed из этого полезного ответаhttps://stackoverflow.com/a/49511949/2028440

sed -e '/ProcessCoverageController.createExampleQueries =/,/ProcessCoverageController.$inject/!b' -e '/ProcessCoverageController.$inject/!d;r content.js' -e 'd' long.js
0
18.03.2021, 22:37

Теги

Похожие вопросы