Вставьте содержимое из файла после совпадения с определенным регулярным выражением, используя sed в bash - PullRequest
0 голосов
/ 11 декабря 2018

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

//**insert_yannyann*//

『// ** insert_yannyann * //』 находится в b.txt, а b.txt простовот так

...

//**insert_yannyann*//

...

a.txt вот так:

1234
5678
9101

Для вставки текстового файла .txt перед шаблоном текста в b.txt, я попробовал это регулярное выражение в Ubuntu18.04 команда bash.

sed -n -i -e '\/\/**insert_yannyann*\/\/ /r a.txt' -e 1x -e '2,${x;p}' -e '${x;p}' b.txt

, даже если я попробовал другой шаблон регулярных выражений.

sed -n -i -e '//?\s*\*[(?=.*\insert_yannyann\b)]*?\*\s*//? /r a.txt' -e 1x -e '2,${x;p}' -e '${x;p}' b.txt

, но sed всегда показывает неверное сообщение для неправильного регулярного выражения, которое я использовал.

Я хочу, чтобы b.txt был таким:

...

1234
5678
9101
//**insert_yannyann*//

...

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

\/\/**insert_yannyann*\/\/

//?\s*\*[(?=.*\insert_yannyann\b)]*?\*\s*//?

Я не уверен, одинаково ли регулярное выражение в разных языках программирования, может кто-нибудь объяснить, почему оно не правильно?

1 Ответ

0 голосов
/ 12 декабря 2018

Perl может быть не ваш вариант, но стоит попробовать.С Perl вы можете сказать:

perl -0777 -ne 'if ($. == 1) {$replace = $_; next} s#(?=//\*\*insert_yannyann\*//)#$replace#g; print' a.txt b.txt > b_new.txt

Тогда b_new.txt содержит:

...

1234
5678
9101
//**insert_yannyann*//

...

Пояснения:

  • -0777Опция Perl приводит к тому, что целые файлы сразу теряются.
  • Perl переменная $. содержит номер строки ввода, который эквивалентен номеру входного файла в этом сценарии использования.С помощью этого значения мы можем переключать обработки для a.txt и b.txt.
  • . Оператор $replace = $_ назначает переменную $replace содержимому a.txt.
  • НаиболееВажной частью будет регулярное выражение s#(?=//\*\*insert_yannyann\*//)#$replace#g.Perl регулярное выражение поддерживает предварительное утверждение с примечанием (?=pattern).Благодаря этой возможности мы можем легко вставить содержимое непосредственно перед указанным шаблоном.

Надеюсь, это поможет.

РЕДАКТИРОВАТЬ

СAWK, вы можете сделать то же самое:

awk 'NR==FNR {replace = replace $0 RS; next}
    {text = text $0 RS}
    END {
        print gensub(/\/\/\*\*insert_yannyann\*\/\//, replace "&", "g", text)
    }' a.txt b.txt > b_new.txt

Дело в том, что строка замены (2-й аргумент gensub()) представляет собой конкатенацию replace, содержимое a.txt и&, который представляет строку, сопоставленную с регулярным выражением.Установка переменной replace перед & вызывает замену перед совпавшим шаблоном.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...