Вставить новые строки перед первым появлением строки параметра - unix - PullRequest
1 голос
/ 17 июня 2020

Исходный файл:

BEGIN SUBRECORD
         Name "New_value"
         Prompt "New_value"
         Default "$PROJDEF"
         ListValues "$PROJDEF\(9)Overwrite"
END SUBRECORD 
MetaBag "CMetaProperty"
............
................
.................
MetaBag "CMetaProperty"
.................
.............
............
MetaBag "CMetaProperty" 

Ожидаемый результат: я хочу добавить новые строки перед первым появлением строки MetaBag "CMetaProperty" и иметь:

BEGIN SUBRECORD
         Name "New_value"
         Prompt "New_value"
         Default "$PROJDEF"
         ListValues "$PROJDEF\(9)Overwrite"
END SUBRECORD
BEGIN SUBRECORD
         Name "Variable"
         Prompt "Variable"
         Default "$PROJDEF"
         ListValues "$PROJDEF\(9)Overwrite"
END SUBRECORD
MetaBag "CMetaProperty"
............
................
.................
MetaBag "CMetaProperty"
.................
.............
............
MetaBag "CMetaProperty"

Я пробовал использовать команду sed , но новые строки вставляются перед всеми вхождениями моей строки параметров.

sed  '/MetaBag "CMetaProperty"/ i       BEGIN SUBRECORD\n         Name "Variable"\n         Prompt "Variable"\n         Default "$PROJDEF"\n         ListValues "$PROJDEF\(9)Overwrite"\n      END SUBRECORD' infile.txt

Как я могу изменить команду?

Ответы [ 2 ]

0 голосов
/ 17 июня 2020

Это может сработать для вас (GNU sed и cat):

<<\! sed -e '/MetaBag/{e cat -' -e ':a;n;ba}' file
Lines of text to insert
    before the first occurrence 
    of the string `MetaBag`

!

После вставленной строки (строк) вызов sed читает / печатает остаток файла.

Строка (и) для вставки помещается в здесь-документ, и при сопоставлении с регулярным выражением /MetaBag/ sed оценивает cat -, который принимает здесь-документ как стандартный ввод и передает его прямо как стандартный вывод при выполнении команды e . Затем сценарий sed запускает al oop, который печатает текущую строку в пространстве шаблонов и заменяет ее следующей строкой, а затем повторяется до конца файла.

NB Команда e оценивает следующие команды это, и эти команды должны заканчиваться новой строкой (или ее эквивалентом). Параметр -e делает это по умолчанию, и поэтому скрипт разделен на две части, чтобы учесть это.

0 голосов
/ 17 июня 2020

Попробуйте

awk '{if($0 ~ /MetaBag/ && $0 !~ /^MetaBag/) gsub( /MetaBag/ , "\n&", $0)}1'

$0 ~ /MetaBag/ <- Проверить, содержит ли строка <strong>MetaBag
$0 !~ /^MetaBag/ <- Проверить, не начинается ли запись с <strong>MetaBag
gsub( /MetaBag/ , "\n&", $0) <- Заменить MetaBag на новую строку + MetaBag </p>

Демо:

$cat test.tst
BEGIN SUBRECORD
         Name "New_value"
         Prompt "New_value"
         Default "$PROJDEF"
         ListValues "$PROJDEF\(9)Overwrite"
END SUBRECORD *MetaBag "CMetaProperty"*
............
................
.................
MetaBag "CMetaProperty"
.................
.............
............
MetaBag "CMetaProperty" 

$awk '{if($0 ~ /MetaBag/ && $0 !~ /^MetaBag/) gsub( /MetaBag/ , "\n&", $0)}1' test.tst
BEGIN SUBRECORD
         Name "New_value"
         Prompt "New_value"
         Default "$PROJDEF"
         ListValues "$PROJDEF\(9)Overwrite"
END SUBRECORD *
MetaBag "CMetaProperty"*
............
................
.................
MetaBag "CMetaProperty"
.................
.............
............
MetaBag "CMetaProperty" 

$
...