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

.귀하의 실수는 (예를 들어 .*)가 :의 개행 문자와 일치하지 않는다고 가정하는 것입니다 awk. sed, 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

관련 정보