awk:コメントの後に行を挿入してソースファイルにインポートします。

awk:コメントの後に行を挿入してソースファイルにインポートします。

非常に一般的な構造を持つ多くのソースファイルがあります。ヘッダーの一部のコメント、一部(オプション)のインポート、ソースコードは次のとおりです。

//
//  AppDelegate.swift
//  settings
//
//  Created by Mikhail Igonin on 14/06/2018.
//  Copyright © 2018 Mikhail Igonin. All rights reserved.
// 


import UIKit
import Fabric
import Crashlytics


@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
    //Other comment
}

注釈とインポートブロックの後に別のインポートを追加する必要があります。したがって、ファイルの先頭に一致する正規表現は次のようになります。

(([\n\s]*)((\/\/.*\n)|(import.*\n)))+

この正規表現は大丈夫だと思います。https://www.regextester.com/index.php?fam=106706

awk次に、次のように新しいインポートを挿入しようとしますgensub

gawk -v RS='^$' '{$0=gensub(/(([\n\s]*)((\/\/.*\n)|(import.*\n)))+/,"\\1\\2\nimport NEW_IMPORT\n\\2",1)}1' test.swift

しかし、うまくいきません。私の正規表現はすべてのファイルと一致します。

//
//  AppDelegate.swift
//  settings
//
//  Created by Mikhail Igonin on 14/06/2018.
//  Copyright © 2018 Mikhail Igonin. All rights reserved.
//


import UIKit
import Fabric
import Crashlytics


@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

}

import NEW_IMPORT

私にとって何が問題ですか?.*正しく機能せず、すべてのファイルと一致しないようです。私はそれを怠惰な(.*?)としてマークしようとしましたが、成功しませんでした。

awkやgensubのないPSソリューションも便利です。

答え1

おそらく大容量ファイルの場合、最も効率的ではありませんが、import ...見つかったLASTステートメントの後に新しいインポート行を挿入します。

tac file | awk '/^import/ && !I {I = 1; print "import New_IMPORT"} 1' | tac

答え2

.あなたの間違いは、(例えば.*)が:の改行文字と一致しないと仮定することですawksed、、grepなどperlとは異なります。javascript(正規表現はawk常に欲が多く、//sフラグが常にオンになっていると思います)。

RSに設定すると、ファイル全体が単一のレコードとして扱われ、^$パターンはawkファイルの最初の改行から最後の改行まで\/\/.*\n一致します。分岐は考慮されません//import.*\n

これを行うより賢い方法があるかもしれませんが、これはファイルのimport NEW_IMPORT最初の行の後にその行を挿入します。import

awk '!e&&/^import/,e=!/^import/{if(e)print "import NEW_IMPORT"}1' test.swift

関連情報