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;D
N
P
D
あなたの場合:
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