ファイルの1行の周りにコンテンツを追加するPOSIXメソッド

ファイルの1行の周りにコンテンツを追加するPOSIXメソッド

私はCで変数の代替定義を提供するスクリプトを使用してファイルを編集する方法を探しています。このオーバーライドは、私がスクリプトを作成しているPOSIXアプリケーションを使用するコンパイラのDフラグによって制御されます。たとえば、トークン名をnice_var次のように変更する必要があるとしますcool_var

入力例:

struct BigThing nice_var;

/* some lines later */

    nice_var->thing = 1;

予想出力:

/* TODO temporary ifdef to facilitate renaming */
#ifdef RENAME_FEATURE_ENABLED
struct BigThing cool_var;
#else
struct BigThing nice_var;
#endif /* RENAME_FEATURE_ENABLED */

/* some lines later */

/* TODO temporary ifdef to facilitate renaming */
#ifdef RENAME_FEATURE_ENABLED
    cool_var->thing = 1;
#else
    nice_var->thing = 1;
#endif /* RENAME_FEATURE_ENABLED */

文字列が表示されるたびに、表示されるプリプロセッサディレクティブパターンで囲む必要があります。これは、連続した行で使用される場合も同様です。

はい、これを行うためにpython / perl / javascriptスクリプトを書くことができます。しかし、この種のファイル編集をサポートできるPOSIXアプリケーションはありますか?私はこれを期待しedたりできますが、ファイル内のすべての項目を繰り返す方法や、検索がファイルの終わりに達した時期を検出する方法がexわかりません。これを検出する方法に関する情報は、目標を達成するために必要なすべてであり得る。edexex

わからない場合は、このスクリプト(と呼びますrenamer)を使用して、次のように "nice_var"が表示されるワークスペース内のすべてのファイルを編集する予定です。

#!/bin/bash -eux
for file in $(grep --files-with-matches --recursive 'nice_var'); do
    renamer --feature-name RENAME_FEATURE_ENABLED --var-name 'nice_var' --replacement 'cool_var' "${file}"
done

回答でコマンドライン引数を処理する必要はありません。私は一致する行の前にコンテンツを追加し、その行を複製するという概念に興味があります。

質問は実際には次のように要約されます。 「パターンを繰り返し検索し、パターンが見つかった行の前後に行を追加する機能をサポートするPOSIXアプリケーションはありますか?ここで追加された行の1つはパターンと一致しますが、パターンは置き換えられます。」

たぶんawk何度もパスしますか?

ベストアンサー1

これは、テキストが変数であるか、コメント行(/* don't change nice_var here */)、文字列内の引用符(char *p = "I've got nice_var here")、さらに別の単語部分(int quitenice_vartoo)であるかにかかわらず、言語構文の知識を必要としない単純な置換を提供する「ベストエフォート」ソリューションです。 。これを正しく行うには、Cパーサーの近似値が必要です。

awk -v src=nice_var -v dst=cool_var -v macro=RENAME_FEATURE_ENABLED '
    $0 ~ src {
        this = that = $0;
        gsub(src, dst, that);
        printf "/* TODO temporary ifdef to facilitate renaming */\n#ifdef %s\n%s\n#else\n%s\n#endif /* %s */\n", macro, that, this, macro;
        next
    }
    1
' sourcefile.c

あなたの例の出力:

/* TODO temporary ifdef to facilitate renaming */
#ifdef RENAME_FEATURE_ENABLED
struct BigThing cool_var;
#else
struct BigThing nice_var;
#endif /* RENAME_FEATURE_ENABLED */

/* some lines later */

/* TODO temporary ifdef to facilitate renaming */
#ifdef RENAME_FEATURE_ENABLED
    cool_var->thing = 1;
#else
    nice_var->thing = 1;
#endif /* RENAME_FEATURE_ENABLED */

これは実際にsrc代替テキストを一致させるために使用される正規表現です。awk私の例は文字列リテラルですが、必ずしもそうではありません。

おすすめ記事