Как изменить значение переменной только в разделе файла?

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

[aaa] a= b c= aaa e = f [bbb] a = b c = aaa e = f
1
задан 6 March 2018 в 11:34

4 ответа

Попробуйте:

$ sed '/^\[aaa\]/,/^\[/{/^\[/b; s/aaa/NEW/}' file.ini [aaa] a= b c= NEW e = f [bbb] a = b c = aaa e = f

Как это работает

Общая команда выглядит как

/^\[aaa\]/,/^\[/{...}

Пара из двух регулярных выражений, разделенных запятой, /^\[aaa\]/,/^\[/ определяет диапазон строк, начинающихся с строки, начинающейся с [aaa] и заканчивающей следующей строкой, начинающейся с [. Для любой строки в этом диапазоне, но только строки в этом диапазоне, выполняются команды в фигурных скобках. Эти команды:

/^\[/b Регулярное выражение /^\[/ ищет строки, начинающиеся с [. Для этих строк выполняется команда b. b обозначает ветку и сообщает sed о прохождении ветки (пропустить) остальные команды. s/aaa/NEW/ Для любой другой строки в диапазоне, это говорит sed заменить любое появление aaa на NEW.

Более подробно /^\[aaa\]/ представляет собой регулярное выражение, которое буквально [ в начале строки сопровождается тремя a, а затем литералом ]. [F18] и ] должны быть экранированы с обратным слэшем, потому что без обратного слэша [ и ] являются активными символами регулярных выражений. Регулярное выражение /^\[ соответствует любой строке, начинающейся с [, где ^ является активным по регулярному выражению символом, который соответствует началу строки, и \[ соответствует литералу [.

1
ответ дан 17 July 2018 в 19:26

Я предлагаю perl для этого - поскольку он поддерживает как замену на месте (опция -i), так и режим абзаца, например

$ perl -00pe 's/aaa/XYZ/g if /^\[aaa\]/' file.ini [XYZ] a= b c= XYZ e = f [bbb] a = b c = aaa e = f

Если вы хотите заменить aaa в разделе, но не в заголовке секции [aaa], тогда вы можете исключить последнее с поисковыми окнами:

$ perl -00pe 's/(?<!\[)aaa(?!\])/XYZ/g if /^\[aaa\]/' file.ini [aaa] a= b c= XYZ e = f [bbb] a = b c = aaa e = f

Чтобы выполнить замену на месте:

perl -i -00pe 's/(?<!\[)aaa(?!\])/XYZ/g if /^\[aaa\]/' file.ini
0
ответ дан 17 July 2018 в 19:26

Попробуйте:

$ sed '/^\[aaa\]/,/^\[/{/^\[/b; s/aaa/NEW/}' file.ini [aaa] a= b c= NEW e = f [bbb] a = b c = aaa e = f

Как это работает

Общая команда выглядит как

/^\[aaa\]/,/^\[/{...}

Пара из двух регулярных выражений, разделенных запятой, /^\[aaa\]/,/^\[/ определяет диапазон строк, начинающихся с строки, начинающейся с [aaa] и заканчивающей следующей строкой, начинающейся с [. Для любой строки в этом диапазоне, но только строки в этом диапазоне, выполняются команды в фигурных скобках. Эти команды:

/^\[/b Регулярное выражение /^\[/ ищет строки, начинающиеся с [. Для этих строк выполняется команда b. b обозначает ветку и сообщает sed о прохождении ветки (пропустить) остальные команды. s/aaa/NEW/ Для любой другой строки в диапазоне, это говорит sed заменить любое появление aaa на NEW.

Более подробно /^\[aaa\]/ представляет собой регулярное выражение, которое буквально [ в начале строки сопровождается тремя a, а затем литералом ]. [F18] и ] должны быть экранированы с обратным слэшем, потому что без обратного слэша [ и ] являются активными символами регулярных выражений. Регулярное выражение /^\[ соответствует любой строке, начинающейся с [, где ^ является активным по регулярному выражению символом, который соответствует началу строки, и \[ соответствует литералу [.

1
ответ дан 23 July 2018 в 20:11

Я предлагаю perl для этого - поскольку он поддерживает как замену на месте (опция -i), так и режим абзаца, например

$ perl -00pe 's/aaa/XYZ/g if /^\[aaa\]/' file.ini [XYZ] a= b c= XYZ e = f [bbb] a = b c = aaa e = f

Если вы хотите заменить aaa в разделе, но не в заголовке секции [aaa], тогда вы можете исключить последнее с поисковыми окнами:

$ perl -00pe 's/(?<!\[)aaa(?!\])/XYZ/g if /^\[aaa\]/' file.ini [aaa] a= b c= XYZ e = f [bbb] a = b c = aaa e = f

Чтобы выполнить замену на месте:

perl -i -00pe 's/(?<!\[)aaa(?!\])/XYZ/g if /^\[aaa\]/' file.ini
0
ответ дан 23 July 2018 в 20:11

Другие вопросы по тегам:

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