
У меня есть файл с именем a.txt. И он содержит следующее. Неизвестно, сколько строк между каждой функцией.
function a(
line 1;
line 2;
line ...;
properties pro = "test";
)
function b(
line 1;
line 2;
line ...;
properties pro= "test";
)
function c(
properties pro= "test";
)
Я хочу редактировать
function b(
line 1;
line 2;
line ...;
properties pro= "test";
)
к следующему
function b(
line 1;
line 2;
line ...;
properties pro= "replace";
)
Можно ли использовать однострочную команду, например sed или awk?
решение1
При условии, что ваши функции разделены на абзацы одной или несколькими пустыми строками, как показано, вы можете использовать awk с пустым разделителем записей. В частности, с GNU awk:
$ gawk '
BEGIN{RS=""}
/^function b/ {sub(/properties pro= "test"/,"properties pro= \"replace\"")}
{printf "%s%s", $0, RT}
' a.txt
function a(
line 1;
line 2;
line ...;
properties pro = "test";
)
function b(
line 1;
line 2;
line ...;
properties pro= "replace";
)
function c(
properties pro= "test";
)
Вы также можете использовать не-GNU awk, но вам нужно будет установить фиксированный разделитель выходных записей, ORS
поскольку RT
разделитель является специфичным для GNU.
Perl предоставляет аналогичный режим абзаца с помощью -00
опции.
С помощью sed вы можете использовать диапазон адресов регулярного выражения, чтобы ограничить область подстановки, например.
$ sed '/^function b/,/^)$/s/properties pro= "test"/properties pro= "replace"/' a.txt
function a(
line 1;
line 2;
line ...;
properties pro = "test";
)
function b(
line 1;
line 2;
line ...;
properties pro= "replace";
)
function c(
properties pro= "test";
)
Однако имейте в виду, что вещи, которые могут быть синтаксически нейтральными в вашем «языке» (например, пустые строкив пределахфункция) может нарушить этот подход — по этой причине регулярные выражения часто являются плохим выбором для таких задач.