Как проверить предыдущую строку в сценарии sed? - PullRequest
0 голосов
/ 18 октября 2018

Мне нужно подавить много предупреждений MSVC в некотором коде C ++.

До:

//...
#include <atomic>
//...

После:

//...
#pragma warning(push)
#pragma warning(disable : 4995)
#include <atomic>
#pragma warning(pop)
//...

Я пытаюсь использовать sed для этой цели:

sed -b -r -i "s;(\s*#include <atomic>.*);#pragma warning(push)\n#pragma warning(disable : 4995)\n\1\n#pragma warning(pop);" macarena.h

Просто заменяет1 строка с 3. Но я хочу запустить этот скрипт несколько раз.Как проверить, соответствует ли предыдущая строка #pragma warning(disable : 4995), и игнорировать текущую строку, если это так?

Ответы [ 3 ]

0 голосов
/ 18 октября 2018

Вы можете использовать это awk:

awk -v p='#pragma warning(disable : 4995)' '
index($0, "#include <atomic>") && prev != p {
      $0 = sprintf("#pragma warning(push)\n%s\n%s\n#pragma warning(pop)", p, $0)
}
{ prev=$0 } 1' file
0 голосов
/ 18 октября 2018

Поскольку линия #include <atomic> находится между pragma warning(disable : 4995) и pragma warning(pop), мы можем просто исключить такие диапазоны

sed -b -r -i '/#pragma warning\(disable : 4995\)/,/#pragma warning\(pop\)/ !{
    s;(\s*#include <atomic>.*);#pragma warning(push)\n#pragma warning(disable : 4995)\n\1\n#pragma warning(pop);
}' macarena.h
0 голосов
/ 18 октября 2018

Perl для спасения!

perl -0777 -pe '$disable = "#pragma warning(disable : 4995)\n";
                $push    = "#pragma warning(push)\n";
                $pop     = "#pragma warning(pop)";
                s/(?<!\Q$disable\E)(#include <atomic>)/$push$disable$1\n$pop/g
               ' -- file
  • -0777 устанавливает «режим slurp», то есть он считывает весь файл в память и обрабатывает его
  • -pвыводит каждый блок после обработки
  • (?<!...) - отрицательный взгляд за утверждением, он означает «не предшествует», т. е. подстановка заменяет включение только в том случае, если ему не предшествует прагма disable.*

    Я считаю его более читабельным, чем решение sed

    sed $'/^#pragma warning(disable : 4995)/{n;n}
          /^#include <atomic>/{i#pragma warning(push)\\\n#pragma warning(disable : 4995)\n;
                               a#pragma warning(pop)\n}' file
    

    , которое пропускает проверку следующей строки при обнаружении отключения.

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