sedを使用して一度に2行を置き換えてインデントする方法は?

sedを使用して一度に2行を置き換えてインデントする方法は?

Pythonファイルから次の2行のコードをsed

多くのコマンドを試しましたが、すべてsedプレーンテキスト行で機能しますが、スペース/タブ^ [ \ s]または^ [ \ t]のある行では機能しません。

def get_user_creds(user):
    # some lines of code
    user.invoke()
    user.process(user)

期待される:

def get_user_creds(user):
    # some lines of code
    user.reinvoke()

答え1

reですべての行を挿入しuser.invoke()てすべての行を削除するのはとても簡単です。user.process(user)問題は、行が一緒に表示されたときにのみ変更することです。

では、常に2行を一緒に処理し、常に追加の行を追加し、両方の行を埋め、最初の行を印刷して削除して、次の行を処理し続ける必要があるsed場合にこのパターンを使用できます。N;P;DNPD

あなたの場合:

sed '$!N;s/user.invoke().*\n.*user.process(user)/user.reinvoke()/;P;D'

(現在はテストできませんが、動作すると確信しています。)

答え2

使用幸せ(以前のPerl_6)

~$ raku -e 'put slurp.subst(:global, / \h+ <( "user.invoke()" \n \h+ "user.process(user)" )> /, "user.reinvoke()" );'  file

入力例:

def get_user_creds(user):
    # some lines of code
    user.invoke()
    user.process(user)

出力例:

def get_user_creds(user):
    # some lines of code
    user.reinvoke()

RakuはPerlファミリーのプログラミング言語です。上記のファイルはslurpコンパイルされた後(つまり、一度に1つずつメモリに読み込まれ)、引数(subst副詞)を使用して繰り返しが実行されます:global。つまり、ファイル内の一致する両方の行が置き換えられます。

マッチャーは、適切なスペース(水平スペースの場合、改行の場合)/ \h+ <( "user.invoke()" \n \h+ "user.process(user)" )> /で囲まれた2つのリテラル文字列(二重引用符で囲む)を探します。一致する場合は...キャプチャタグを使用して置き換えるコンテンツを説明します。ここでの初期値は\h\n<()>\h+含まれていませんマークをキャプチャして新しく挿入された文字列(例:「インデントの尊重」)。

通常、正規表現をエスケープするのは痛いです。ただし、Rakuはリテラル文字列(上記の二重引用符)を受け入れてプロセスを簡素化します。引用符が問題なら、バックスラッシュも大丈夫です。文字を文字通り受け入れるには、[alnumまたはunderscore]以外のすべての文字をバックスラッシュします。これは、バックスラッシュではなく、[数字または下線]文字("" dotsと同じカテゴリ.)が現在特別な意味を割り当てられていない場合でも、将来の特別な意味を持たないようにします。

参考までに、キャプチャ/交換について非常に具体的に説明することができます。文字列 "user"の下。そして「invoke()」がキャプチャされ、「re」が代替アイテムに挿入され、「reinvoke()」が生成されます。

~$ raku -e 'put S:g/ \h+ <( ("user.") ("invoke()") \n \h+ "user.process(user)" )> /$0re$1/ given slurp();'  file

#OR

~$ raku -e 'put S:g[ \h+ <( ("user.") ("invoke()") \n \h+ "user.process(user)" )> ] = "$0re$1" given slurp();'  file

https://docs.raku.org/言語/regexes
https://raku.org

関連情報