RegEx для замены содержимого группы захвата с помощью sed [закрыто]

Esta es una solución simple con Perl agregando las líneas a la línea (cada línea )con contentsin analizar el documento JSON. Este es un -trazador de líneas (copia y pega en tu línea de comando ). Supongo que quieres esto:

<in perl -nple'$_.="\\nexport KAFKA_HEAP_OPTS=\"-Xmx8g -Xms8g\"\\nexport KAFKA_JVM_PERFORMANCE_OPTS=\" -XX:MetaspaceSize=96m -XX:+UseG1GC -XX:MaxGCPauseMillis=20 -XX:InitiatingHeapOccupancyPercent=35 -XX:G1HeapRegionSize=16M -XX:MinMetaspaceFreeRatio=50 -XX:MaxMetaspaceFreeRatio=80\"\\n\"" 
if/^\s+"content"/ '

Aquí inal principio está el archivo de entrada. Obtiene la salida en la pantalla, que puede ajustar fácilmente. También puede hacer que Perl modifique el archivo en su lugar usando el interruptor -i. (Infórmate primero.)

La salida es esta:

{
  "href" : "http://master02:8080/api/v1/clusters/HDP/configurations?type=kafka-env&tag=version1527250007610",
  "items" : [
    {
      "href" : "http://master02:8080/api/v1/clusters/HDP/configurations?type=kafka-env&tag=version1527250007610",
      "tag" : "version1527250007610",
      "type" : "kafka-env",
      "version" : 8,
      "Config" : {
        "cluster_name" : "HDP",
        "stack_id" : "HDP-2.6"
      },
      "properties" : {
        "content" : "\n#!/bin/bash\n\n# Set KAFKA specific environment variables here.\n\n# The java implementation to use.\nexport JAVA_HOME={{java64_home}}\nexport PATH=$PATH:$JAVA_HOME/bin\nexport PID_DIR={{kafka_pid_dir}}\nexport LOG_DIR={{kafka_log_dir}}\nexport KAFKA_KERBEROS_PARAMS={{kafka_kerberos_params}}\nexport JMX_PORT=9997\n# Add kafka sink to classpath and related depenencies\nif [ -e \"/usr/lib/ambari-metrics-kafka-sink/ambari-metrics-kafka-sink.jar\" ]; then\n  export CLASSPATH=$CLASSPATH:/usr/lib/ambari-metrics-kafka-sink/ambari-metrics-kafka-sink.jar\n  export CLASSPATH=$CLASSPATH:/usr/lib/ambari-metrics-kafka-sink/lib/*\nfi\n\nif [ -f /etc/kafka/conf/kafka-ranger-env.sh ]; then\n. /etc/kafka/conf/kafka-ranger-env.sh\nfi",\nexport KAFKA_HEAP_OPTS="-Xmx8g -Xms8g"\n export KAFKA_JVM_PERFORMANCE_OPTS=" -XX:MetaspaceSize=96m -XX:+UseG1GC -XX:MaxGCPauseMillis=20 -XX:InitiatingHeapOccupancyPercent=35 -XX:G1HeapRegionSize=16M -XX:MinMetaspaceFreeRatio=50 -XX:MaxMetaspaceFreeRatio=80"\n"
        "is_supported_kafka_ranger" : "true",
        "kafka_log_dir" : "/var/log/kafka",
        "kafka_pid_dir" : "/var/run/kafka",
        "kafka_user" : "kafka",
        "kafka_user_nofile_limit" : "128000",
        "kafka_user_nproc_limit" : "65536"
      }
    }
  ]

Como puede ver, hice una corrección aquí:

export KAFKA_HEAP_OPTS="-Xmx8g -Xms8g"\nexport KAFKA_JVM_PERFORMANCE_OPTS=" -XX:MetaspaceSize=96m -XX:+UseG1GC -XX:MaxGCPauseMillis=20 -XX:InitiatingHeapOccupancyPercent=35 -XX:G1HeapRegionSize=16M -XX:MinMetaspaceFreeRatio=50 -XX:MaxMetaspaceFreeRatio=80"\n

Cambié el diseño de la opción -XXy el final es -XX:MaxMetaspaceFreeRatio=80"\n, y no - XX:MaxMetaspaceFreeRatio=80\n", como lo requería. Así que cambia esto si eso es lo que realmente quieres. También la nueva línea antes del shebang es lo que eliminaría. Pero te he dejado esto.

1
07.06.2019, 13:14
2 ответа

1 )Для шаблона с большим количеством косых черт вы должны использовать другой разделитель для команды s, чтобы сделать ее более читаемой (вам не нужно экранировать косые черты, тогда ).

2 )Похоже, вы используете расширенные регулярные выражения, поэтому вам нужно установить для параметра -Eзначениеsed

3 )Если вы используете альтернативные струны для части паттерна, вам нужно окружить это (), например(messages|secure)

4 )Замещающая часть(/index=window)должна быть частью скрипта, а не отделяться как аргумент.

5 )Кроме того, в команде sотсутствует закрывающий разделитель

6)(?s)and(? :)`— это не регулярные выражения, а расширения Perl, поэтому не используйте их здесь. И поскольку двоеточие здесь не имеет особого значения, вам не нужно экранировать его (спасибо, @Stéphane Chazelas)

7)sedработает построчно, поэтому ваш \nникогда не совпадет, пока вы не соедините строки (, чего вы не делаете)

Теперь смею предположить, что вы пытались сделать. :В журналах messagesи secureизмените следующую строку index=на index=secure. Правильный?

Итак, ваша команда s/index=/index=secure/. Но вы хотите применить его только к определенным группам. Для этогоsedимеет параметр фильтрации для применения команд только к строкам (или группе строк ), которые соответствуют фильтру. Один из способов адресации строк шаблону, который необходимо сопоставить. Если вы хотите адресовать диапазон строк, вы указываете два адреса (, начальный и конечный адрес ), разделенные запятой :

.
sed -E '\_\[WinEventLog://(Application|Security|System|ForwardedEvents|Setup)\]_,/index *=/s/index =/index = window/' inputs.conf

На второй команде я могу показать, как еще больше упростить команду. :Вы можете удалить соответствующий шаблон в команде s. Это означает, что последний шаблон используется снова, который является вторым адресом диапазона фильтра, поэтому его не нужно повторять.

А вместо повторения шаблона при замене можно написать &, что вставит все совпадение:

sed -i -E '\_\[monitor:///var/log/(messages|secure)\]_,/index=/s//&secure/' *linux*/local/inputs.conf

Последняя подсказка. :Не используйте опцию -i, пока не будете удовлетворены результатом. Вы можете легко испортить свой файл таким образом, особенно если у вас нет опыта работы с этим инструментом.

Обновление

С обновленным вопросом кажется возможным, что уже есть некоторая index=fooнастройка, которую необходимо заменить. Просто измените замену:

sed -E '/(Application|Security|System|ForwardedEvents|Setup)]/,/index *=.*/s//index = window/' inputs.conf

и

sed -i -E '/messages]|secure]/,/index *=.*/s//index=secure/' *linux*/local/inputs.conf

(дальнейшее упрощение схемы, предложенной тердоном)

1
27.01.2020, 23:41

Это было бы гораздо проще сделать на Perl. Исполняемый файл perlимеет так называемый «режим абзаца» (-00), в котором «строка» определяется двумя последовательными \nсимволами (, то есть пустой строкой ). Это позволяет perlработать с абзацами вместо строк. Так что вы можете просто сделать:

$ perl -00pe 'if(m,^\[WinEventLog://(Application|Security|System|ForwardedEvents|Setup)\],){s/(index\s*=)\s*[^\n]*/$1 window inputs.conf\n\n/}' file1
[WinEventLog://Application]
checkpointInterval = 5
current_only = 0
disabled =0 
start_from = oldest
index = window inputs.conf

[WinEventLog://Security]
checkpointInterval = 5
current_only = 0
disabled =0 
start_from = oldest
index = window inputs.conf

[WinEventLog://System]
checkpointInterval = 5
current_only = 0
disabled =0 
start_from = oldest
index = window inputs.conf

[WinEventLog://ForwardedEvents]
checkpointInterval = 5
current_only = 0
disabled =0 
start_from = oldest
index = window inputs.conf

[WinEventLog://Setup]
checkpointInterval = 5
current_only = 0
disabled =0 
start_from = oldest
index = window inputs.conf

И:

$ perl -00pe 'if(m,^\[monitor:///var/log/(messages|secure)\],){s/(index\s*=)\s*[^\n]*/$1 secure\n\n/}' file2
[monitor:///var/log/cron]
sourcetype=linux_secure
index=

[monitor:///var/log/secure]
sourcetype=linux_secure
index= secure

[monitor:///var/log/messages]
sourcetype=linux
index= secure

[monitor:///var/log/spooler]
sourcetype=syslog
index = 

[monitor:///var/log/audit/audit.log]
sourcetype=syslog
index=

[monitor:///var/log//maillog]
sourcetype=syslog
index=

Тем не менее, поскольку ваши файлы имеют достаточно стабильный формат, вы можете еще больше упростить до:

$ perl -00lpe '$_.= "window inputs.conf" if m,//(Application|Security|System|ForwardedEvents|Setup)\],;' file1
[WinEventLog://Application]
checkpointInterval = 5
current_only = 0
disabled =0 
start_from = oldest
index = window inputs.conf

[WinEventLog://Security]
checkpointInterval = 5
current_only = 0
disabled =0 
start_from = oldest
index = window inputs.conf

[WinEventLog://System]
checkpointInterval = 5
current_only = 0
disabled =0 
start_from = oldest
index = window inputs.conf

[WinEventLog://ForwardedEvents]
checkpointInterval = 5
current_only = 0
disabled =0 
start_from = oldest
index = window inputs.conf

[WinEventLog://Setup]
checkpointInterval = 5
current_only = 0
disabled =0 
start_from = oldest
index = window inputs.conf

И:

$ perl -00lpe '$_.="secure" if m,/(messages|secure)\],' file2
[monitor:///var/log/cron]
sourcetype=linux_secure
index=

[monitor:///var/log/secure]
sourcetype=linux_secure
index=secure

[monitor:///var/log/messages]
sourcetype=linux
index=secure

[monitor:///var/log/spooler]
sourcetype=syslog
index = 

[monitor:///var/log/audit/audit.log]
sourcetype=syslog
index=

[monitor:///var/log//maillog]
sourcetype=syslog
index=
1
27.01.2020, 23:41

Теги

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