2017-04-01 4 views
0

開始パターンと終了パターン内のパターンを見つけて修正して、複数のファイルを更新したいと考えています。 これがawk/sedで実現できる場合、私はステップを解消しています。開始パターンと終了パターン内のパターンを見つけて修正してファイルを更新する

  1. 「startpat」と「endpat」内の文字列の出現を検索
  2. は、例えば、インスタンスの文字列を変更(開始と終了の間の線をキャプチャ): 更新「SSS:CCC」 ':DDD SSS' アップデート 'BRR:MMM' 'BRR:REL/CCC' にする
  3. は今ステップ2.
  4. からアップデート列と 'endpat' から 'startpat' から行の新しいセットを作成します'---'の後にファイルの先頭に追加します。 「:AAA SSS」と「BRR:REL/AAA」

注:最も重要な維持たいと思い、それが文字列に一致した場合

  • は「startpat」と「endpat」からラインのセットの最後の発生を削除します。私はjson/yamlファイルで作業しています。

    入力ファイル形式(ファイルの解析中にPSコメント行//を無視する):処理後の

    --- 
    - startpat:  // Startpat - make this line inclusive 
        ... 
        sss: ccc  // pattern to be modified 
        ppp: 'vvv' 
        pname: 'vvv' 
        brr: 'mmm'  // pattern to be modified 
        jdk: jdk8 
        jdks: 
         - jdk8 
         - jdk7 
        file: 
         - test: 
          exec: 'input' 
        ... 
    
    - startpat:  // Endpat - make this line exclusive 
    

    予想される出力:

    --- 
    - startpat: 
        sss: ddd 
        ppp: 'vvv' 
        pname: 'vvv' 
        brr: 'mmm' 
        jdk: jdk8 
        jdks: 
         - jdk8 
         - jdk7 
        file: 
         - test: 
          exec: 'input' 
    
    - startpat:  // Startpat 
        .... 
        sss: ccc 
        ppp: 'vvv' 
        pname: 'vvv' 
        brr: 'mmm' 
        jdk: jdk8 
        jdks: 
         - jdk8 
         - jdk7 
        file: 
         - test: 
          exec: 'input' 
        ... 
    
    - startpat:  // Endpat 
    
  • 答えて

    2

    私は最も簡単な方法は、AN内のすべての行を保存することだと思いますアレイ。あなたが開始するには:

    $ cat f.awk 
    BEGIN { 
        # build regualr expressions to match "start pattern" and 
        # "end pattern" (in the question they are the same) 
    
        ws = "[\\t ]*"   # white-spaces 
        sp = "^" ws "- startpat:" # [s]tart [p]attern 
        ep = sp     # [e]nd [p]attern 
    
        # a regular expression to match "---" 
        # possibly suraunded by white-spaces 
        op = "^" ws "---" ws "$" # where to start appending 
    } 
    
    { f[NR] = $0 } # save every line to an array 
    
    END { 
        n = NR # number of line in the file 
    
        find_blocks() # set `nb` (number of blocks), `ss` `ee` 
    
        for (ib = 1; ib <= nb; ib++) 
         process_block(ss[ib], ee[ib]) # pass start and end of each block 
                 # set `nex' (number of extra lines) and `eex' 
        write() 
    } 
    
    function find_blocks( i, l, is, ie) { 
        for (i = 1; i <= n; i++) { 
         l = f[i] 
         if (is > ie && l ~ ep) ee[++ie] = i # end 
         if (   l ~ sp) ss[++is] = i # start 
        } 
        nb = ie 
    } 
    
    function process_block(is, ie, i, l) { 
        for (i = is + 1; i <= ie - 1; i++) { 
         l = f[i] 
         # modify a line (an example) 
         if (l ~ /brr:/) sub(/'mmm'/, "'rel/cc'", l) 
    
         eex[++nex] = l # push the line to another array 
        } 
    } 
    
    function write( i, j, l) { 
        i = 1 
        while (i <= n) { # print everything before "---" 
         print l = f[i++] 
         if (l ~ op) break 
        } 
    
        for (j = 1; j <= nex; j++) # add an extra part 
         print eex[j] 
    
        while (i <= n)   # print the part after "---" 
         print f[i++] 
    } 
    

    入力ファイル

    $ cat input 
    --- 
    - startpat: 
        XXXXX 
        brr: 'mmm' 
    - startpat: 
        YYYYY   
        brr: 'mmm' 
    - startpat: 
    

    使用法:

    awk -f f.awk input 
    

    を出力:

    --- 
        XXXXX 
        brr: 'rel/cc' 
        YYYYY   
        brr: 'rel/cc' 
    - startpat: 
        XXXXX 
        brr: 'mmm' 
    - startpat: 
        YYYYY   
        brr: 'mmm' 
    - startpat: 
    
    +0

    スクリプトのどの部分が明確ではないでしょうか? – slitvinov

    +1

    @askbコメントをいくつか追加しました。 http://manpages.ubuntu.com/manpages/precise/man1/original-awk.1.html – slitvinov

    +0

    Awkを学ぶ最も良い方法はArnold RobbinsのEffective Awk Programming、第4版です。 –

    関連する問題