sed ファイル内の特定の段落間の文字列を編集する

sed ファイル内の特定の段落間の文字列を編集する

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 行コマンドを使用することは可能ですか?

答え1

関数が 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 も使用できますが、区切り文字は GNU 固有であるORSため、固定の出力レコード区切り文字を設定する必要があります。RT

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";
)

ただし、あなたの「言語」では文法的に中立な可能性のあるもの(空白行など)は、内で関数などではこのアプローチが崩れる場合があります。このため、正規表現はこのようなタスクには適さないことがよくあります。

関連情報