регулярное выражение соответствует тексту в фигурных скобках и печатает целые фигурные скобки

Sí, así es como tradicionalmente le dices a un sistema de inicio regular en qué estado debe iniciarse. Si está ejecutando sysv -init (o prácticamente cualquier sistema de inicio ampliamente utilizado que no sea systemd ), puede poner un número entre 1 y 5 al final de los argumentos del kernel y se iniciará en ese el nivel de ejecución (1 es siempre el modo de usuario único -, los otros están definidos por el sistema, 3 o 4 es lo que la mayoría de las distribuciones de Linux han usado convencionalmente como predeterminado ). Si está utilizando systemd, puede pasar singleo emergencyal final de los argumentos del kernel para iniciar en esos modos respectivamente.

Sin embargo, usar este mecanismo para pasar argumentos arbitrarios es un poco difícil porque el kernel hace el mínimo absoluto de análisis, lo que significa en particular que:

  • Los argumentos con espacios en blanco no se pueden pasar en absoluto, porque el núcleo no analiza las cadenas entre comillas (, es decir, 'some string'se analiza como dos argumentos 'someystring').
  • No puede hacer referencia a ninguna variable de entorno en absoluto, porque el kernel no realiza la sustitución de variables (, lo que normalmente hace el shell desde el que está ejecutando el comando incluso antes de que inicie el comando ).
  • En general, los argumentos deben poder interpretarse correctamente bajo la configuración regional POSIX C (esencialmente US ASCII ), lo que arroja la internacionalización por la ventana a menos que desee usar algo como base64 o punycode.
  • Hay un límite superior sobre la cantidad de datos que se pueden pasar en los argumentos del núcleo, pero olvidé cuál es.

Estas limitaciones combinadas son la razón por la que no puede encontrar nada en Google sobre hacer este tipo de cosas, ningún ingeniero de integración de sistemas en su sano juicio lo hace, porque es mucho más esfuerzo evitar las limitaciones anteriores que simplemente escriba un script que contenga todos los argumentos requeridos y llámelo en su lugar.

1
10.10.2018, 15:33
4 ответа

попробуй это,

perl -0777 -ne '/([^\n]*{[^}]*(yyyyyyyyy991)[^}]*})/ && print "$1\n"' file

Пояснение:

  • perl -0777Запустите perl и проглотите весь файл одной строкой.
  • -neдля каждой строки(n)выполните(e)следующее.
  • /(pattern)/ && print "$1\n"сопоставьте шаблон регулярного выражения и добавьте его в качестве первой соответствующей группы ($1), а затем распечатайте его.

Узор:

  • [^\n]*{... }Соответствует чему угодно от начала строки, включая "{", до следующего "}"
  • Поскольку ...означает[^}]*(yyyyyyyyy991)[^}]*:
    • Соответствует любому символу, отличному от}
    • должен где-то включать yyyyyyyyy991.
3
28.04.2021, 23:42

Допустим, ваш файл конфигурации называется config.dat и имеет стандартный формат. Это означает, что у вас есть только одна строка до yyyyyyyyy991 и пять строк после нее, тогда эта команда поможет вам получить желаемый результат:

grep -B 1 -A 5 "yyyyyyyyy991" config.dat

define host{
        host_name yyyyyyyyy991
        use aix-server
        alias
        hostgroups +bu-automotiveprd,screen-automotiveprd2
        address YYY.YYY.YYY.YYY
}

Отgrepмужчина:

Context control flage:
  -B, --before-context=NUM  print NUM lines of leading context
  -A, --after-context=NUM   print NUM lines of trailing context

Другое решение, если файл config.dat не является стандартным , что означает, что ключевое слово "yyyyyyyyy991" не соответствует одному и тому же шаблону в каждом разделе, тогда awkможет делать то, что вы хотите, как следует:

 awk -v RS='' '/host_name yyyyyyyyy991/' config.dat

RS= изменяет разделитель входных записей с новой строки на пустые строки. Если какое-либо поле в записи содержит /host _name yyyyyyyyy991/, распечатайте запись.

Согласно posix

Если RS имеет значение null, то записи разделяются последовательностями, состоящими из плюс одной или нескольких пустых строк, начальные или конечные пустые строки не должны приводить к пустым записям в начале или конце ввода, а всегда должно быть разделитель полей, независимо от значения FS.

Выходные абзацы не будут разделены, так как выходной разделитель остается одной новой строкой. Чтобы убедиться, что между выходными абзацами есть пустая строка, установите разделитель выходных записей на две новые строки.

2
28.04.2021, 23:42

Если ваш grepподдерживает это, вы можете использовать параметр -z, чтобы заставить его глотать весь файл:

$ grep -ozE 'define[^}]*host_name yyyyyyyyy991.+?}.' file
define host{
        host_name yyyyyyyyy991
        use aix-server
        alias
        hostgroups +bu-automotiveprd,screen-automotiveprd2
        address YYY.YYY.YYY.YYY
}

Используемые опции grep— это (со страницы manGNUgrep):

  -z, --null-data
          Treat  input  and output data as sequences of lines, each terminated by a
          zero byte (the ASCII NUL character) instead of a newline.  Like the -Z or
          --null  option,  this  option  can  be used with commands like sort -z to
          process arbitrary file names.
  -o, --only-matching
          Print only the matched (non-empty) parts of a matching  line,  with  each
          such part on a separate output line.
  -E, --extended-regexp
          Interpret PATTERN as an extended regular expression (ERE, see below).

Регулярное выражение ищет слово define, за которым следует 0 или более не-}символов ([^}]*), затем host_name yyyyyyyyy991и затем все до первого}(.+?)плюс следующий символ (, последний .), который будет соответствовать новой строке.


Однако лично я бы сделал нечто подобное, используя режим абзаца Perl:

$ perl -00 -ne 'print if /yyyyyyyyy991/' file
define host{
        host_name yyyyyyyyy991
        use aix-server
        alias
        hostgroups +bu-automotiveprd,screen-automotiveprd2
        address YYY.YYY.YYY.YYY
}

-00указывает perlчитать входной файл как абзацы, поэтому каждая запись представляет собой абзац (, определяемый двумя последовательными \nсимволами )вместо строки. Затем -neозначает «Прочитать каждую входную запись и применить к ней сценарий, заданный -e». Сам скрипт просто печатает любые записи, соответствующие нужному шаблону.

2
28.04.2021, 23:42

Использованиеsed:

sed 'H;/^define host{$/h;/^}/{g;/host_name yyyyyyyyy991\n/p};d' file

Шаг -на -шаг:

H                  # append line to hold space
/^define host{$/h  # start of entry: copy to hold space (overwrites previous content)
/^}/{              # end of entry:
        g                            # retrieve whole entry from hold space
        /host_name yyyyyyyyy991\n/p  # if host matched, display the whole entry
}
d                  # no other output
0
28.04.2021, 23:42

Теги

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