1

古い F77 コードを gfortran でコンパイルするように変換しています。次の方法で使用される一連の RECORDS があります。

RecoRD /TEST/ this
this.field = 1
this.otherfield.sumthin = 2
func = func(%val(ThIs.field,foo.bar,this.other.field))

私はこれらすべてをTYPEに変換しようとしています:

TYPE(TEST) this
this%field = 1
this%otherfield%sumthin = 2
func = func(%val(ThIs%field,foo.bar,this%other%field))

私はsedで大丈夫で、ファイルを処理してRECORD宣言をTYPE宣言に置き換えることができますが、Linuxツールを使用して前処理タイプのスクリプトを記述して、this.field表記をthis%field表記に変換する方法はありますか? 宣言されたレコード名を認識し、それを具体的にターゲットにして、誤って他の変数を壊さないようにする必要があると思います。また、含まれているファイルをどのように処理できるか考えていますか? それはかなり厄介になる可能性があると思いますが、誰かが同様のことをした場合は、解決策に含めるとよいでしょう.

編集:私はpython 2.4を利用できます。

4

2 に答える 2

2

そのためにPythonを使用できます。次のスクリプトは、標準入力からテキストを読み取り、要求した置換を使用して標準出力に出力します。

import re
import sys

txt = sys.stdin.read()
names = re.findall(r"RECORD /TEST/\s*\b(.+)\b", txt, re.MULTILINE)
for name in list(set(names)):
    txt = re.sub(r"\b%s\.(.*)\b"%name, r"%s%%\1"%name, txt, 
                 re.MULTILINE)
sys.stdout.write(txt)

編集: Python 2.4 の場合: はい、形式を % に置き換える必要があります。sub()サブフィールドを持つ構造については、以下のように呼び出しで関数を使用することで簡単に実現できます。大文字と小文字を区別しないことも追加しました。

import re
import sys

def replace(match):
    return match.group(0).replace(".", "%")

txt = sys.stdin.read()
names = re.findall(r"RECORD /TEST/\s*\b(.+)\b", txt, re.MULTILINE)
for name in names:
    txt = re.sub(r"\b%s(\.\w+)+\b" % name, replace, txt,
                 re.MULTILINE | re.IGNORECASE)
sys.stdout.write(txt)
于 2013-02-05T08:04:15.247 に答える
1

GNU awk の場合:

$ cat tst.awk
/RECORD/ { $0 = gensub(/[^/]+[/]([^/]+)[/]/,"TYPE(\\1)",""); name=tolower($NF) }
{
   while ( match(tolower($0),"\\<" name "[.][[:alnum:]_.]+") ) {
      $0 = substr($0,1,RSTART-1) \
           gensub(/[.]/,"%","g",substr($0,RSTART,RLENGTH)) \
           substr($0,RSTART+RLENGTH)
   }
}
{ print }

$ cat file
RECORD /TEST/ tHiS
this.field = 1
THIS.otherfield.sumthin = 2
func = func(%val(ThIs.field,foo.bar,this.other.field))

$ awk -f tst.awk file
TYPE(TEST) tHiS
this%field = 1
THIS%otherfield%sumthin = 2
func = func(%val(ThIs%field,foo.bar,this%other%field))

this.field入力を変更して、1行に複数回出現し、他の「。」と混在するとどうなるかを示すことに注意してください。参照 ( foo.bar)。それがどのように機能するかを示すために、「this」の大文字と小文字が混在するオカレンスもいくつか追加しました。

インクルードされたファイルの処理方法に関する以下の質問への回答として、次の 1 つの方法があります。

このスクリプトは、「サブファイルを含める」というすべての行を展開するだけでなく、結果を tmp ファイルに書き込み、ARGV[1] (最高レベルの入力ファイル) をリセットし、ARGV[2] (tmp ファイル) をリセットしません。 、tmp ファイルに保存されているため、展開の結果に対して通常のレコード解析を awk に実行させます。それが必要ない場合は、標準出力に「印刷」して、tmp ファイルまたは ARGV[2] へのその他の参照をすべて削除してください。

awk 'function read(file) {
       while ( (getline < file) > 0) {
           if ($1 == "include") {
                read($2)
           } else {
                print > ARGV[2]
           }
       }
       close(file)
   }
   BEGIN{
      read(ARGV[1])
      ARGV[1]=""
      close(ARGV[2])
   }1' a.txt tmp

現在のディレクトリにあるこれらの 3 つのファイルを指定して上記を実行した結果:

  a.txt             b.txt              c.txt
  -----             -----              -----
  1                 3                  5
  2                 4                  6
  include b.txt     include c.txt
  9                 7
  10                8

1 から 10 までの数字を出力し、"tmp" という名前のファイルに保存します。

したがって、このアプリケーションでは、上記のスクリプトの末尾にある数字「1」を、上記の最初のスクリプトの内容に置き換えることができます。これは、展開されたファイルの内容を含む tmp ファイルで機能します。

于 2013-02-05T14:21:04.080 に答える