Я ищу помощь с примером использования команды sed. Я хочу изменить значение переменной в разделе в текстовом файле, в этом примере я хочу изменить значение aaa в разделе [aaa] на новое значение, как изменить его с помощью sed или другой команды.
[aaa]
a= b
c= aaa
e = f
[bbb]
a = b
c = aaa
e = f
Попробуйте:
$ 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] и ] должны быть экранированы с обратным слэшем, потому что без обратного слэша [ и ] являются активными символами регулярных выражений. Регулярное выражение /^\[ соответствует любой строке, начинающейся с [, где ^ является активным по регулярному выражению символом, который соответствует началу строки, и \[ соответствует литералу [.
Я предлагаю 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
Попробуйте:
$ 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] и ] должны быть экранированы с обратным слэшем, потому что без обратного слэша [ и ] являются активными символами регулярных выражений. Регулярное выражение /^\[ соответствует любой строке, начинающейся с [, где ^ является активным по регулярному выражению символом, который соответствует началу строки, и \[ соответствует литералу [.
Я предлагаю 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