Sed + сопоставить слово в строках и заменить значение некоторыми условиями

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

more Hadoop-specific-environment.txt
.
.

export HADOOP_DATA_NODE_OPTS = "-server -XX:ParallelGCThreads=4 -XX:+UseConcMarkSweepGC -XX:ErrorFile=/var/log/hadoop/$USER/hs_err_pid%p.log 
.
.

поэтому мы подготовили следующий синтаксис sed

val-32
HADOOP_OPTS=HADOOP_DATA_NODE_OPTS

sed -i "/$HADOOP_OPTS/s/-XX:ParallelGCThreads=[0-9]*/-XX:ParallelGCThreads=$val/"  Hadoop-specific-environment.txt

выше sed работает нормально, но у нас есть некоторые проблемы

  1. в случае, если ключ ParallelGCThreads имеет значение null (без значения), замена не удастся

    ПараллельGCThreads=

  2. значение будет заменено, четная строка находится в комментарии

    #export HADOOP_DATA_NODE_OPTS=

каковы правильные исправления для решения вышеуказанных проблем

любое другое предложение будет приветствоваться, включая один вкладыш Perl

🤔 А знаете ли вы, что...
Bash поддерживает множество встроенных команд для работы с файлами и процессами.


85
2

Ответы:

Решено

=[0-9]* следует заменить на (=[0-9]*)?.

^[^#]* следует добавить в начале первого регулярного выражения.

sed -i -E "/^[^#]*$HADOOP_OPTS/s/-XX:ParallelGCThreads(=[0-9]*)?/-XX:ParallelGCThreads=$val/" Hadoop-specific-environment.txt

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

$ cat Hadoop-specific-environment.txt 
export HADOOP_DATA_NODE_OPTS = "-server -XX:ParallelGCThreads=4 -XX:+UseConcMarkSweepGC -XX:ErrorFile=/var/log/hadoop/$USER/hs_err_pid%p.log"
export HADOOP_DATA_NODE_OPTS = "-server -XX:ParallelGCThreads= -XX:+UseConcMarkSweepGC -XX:ErrorFile=/var/log/hadoop/$USER/hs_err_pid%p.log"
** test test test **
export HADOOP_DATA_NODE_OPTS = "-server -XX:+UseConcMarkSweepGC -XX:ErrorFile=/var/log/hadoop/$USER/hs_err_pid%p.log -XX:ParallelGCThreads = "
#export HADOOP_DATA_NODE_OPTS = "-server -XX:+UseConcMarkSweepGC -XX:ErrorFile=/var/log/hadoop/$USER/hs_err_pid%p.log -XX:ParallelGCThreads = "
** some other exports **

$ sed -r '/^[^#].*HADOOP_DATA_NODE_OPTS=/ s/^(.*ParallelGCThreads)=[0-9]*(.+)$/\1=42\2/' Hadoop-specific-environment.txt
export HADOOP_DATA_NODE_OPTS = "-server -XX:ParallelGCThreads=42 -XX:+UseConcMarkSweepGC -XX:ErrorFile=/var/log/hadoop/$USER/hs_err_pid%p.log"
export HADOOP_DATA_NODE_OPTS = "-server -XX:ParallelGCThreads=42 -XX:+UseConcMarkSweepGC -XX:ErrorFile=/var/log/hadoop/$USER/hs_err_pid%p.log"
** test test test **
export HADOOP_DATA_NODE_OPTS = "-server -XX:+UseConcMarkSweepGC -XX:ErrorFile=/var/log/hadoop/$USER/hs_err_pid%p.log -XX:ParallelGCThreads=42"
#export HADOOP_DATA_NODE_OPTS = "-server -XX:+UseConcMarkSweepGC -XX:ErrorFile=/var/log/hadoop/$USER/hs_err_pid%p.log -XX:ParallelGCThreads = "
** some other exports **

Объяснение регулярного выражения:

/^[^#].*HADOOP_DATA_NODE_OPTS=/ -> must be an uncommented HADOOP_DATA_NODE_OPTS variable.

s/^(.*ParallelGCThreads)=[0-9]*(.+)$/
^(.*ParallelGCThreads)   -> Group \1: Everything until variable
=[0-9]*                  -> skipped, overwritten later
(.+)$                    -> Group \2: The rest you want

/\1=42\2/
\1                       -> Show first group
=42                      -> Use 42 ParallelGCThreads
\2                       -> Show second group