A2P(1) USER COMMANDS A2P(1)
NAME
a2p - Awk から Perl へのトランスレータ
SYNOPSIS
a2p [options] filename
DESCRIPTION
a2p は、コマンドライン上で指定された (もしくは、標準入力から
の) awk スクリプトを解釈し、対応する Perl スクリプトを標準出
力に出力します。
オプション
オプションには、以下のものがあります:
-D<number>
デバッグフラグを設定する。
-F<character>
入力の awk スクリプトを実行する時に、いつも指定したもの
と同じ -F スイッチを付けることを a2p に教えます。
-n<fieldlist>
入力の split 結果を配列にする必要がない場合に、入力フィ
ールドの名前を指定します。 パスワードファイルを処理す
る awk スクリプトを変換するときには、
a2p -7 -nlogin.password.uid.gid.gcos.shell.home
のようになるでしょう。 フィールド名の区切り文字は、何
でも使えます。
-<number>
入力フィールドの数が、常にこの数値だけであることを a2p
に伝えます。
考慮点
a2p は人間が行なうような、うまい変換はできませんが、だいたい
は、かなり良いものとなります。 中には、出来上がった Perl ス
クリプトを調べて、多少手を加えた方が良いこともあります。 こ
こでは、その幾つかを、順不同で示すことにします。
awk では、文字列を強制的に数値として解釈させるために、int()
で括ることがあり、たとえ引数が常に整数であってもそのままにし
ておくことがあります。 こういったことは、通常 Perl では不要
ですが、a2p では引数が常に整数であるかが判断できないので、そ
のままにしてあります。 必要ない場合には、削ってかまいません。
Perl では、数値の比較と文字列の比較を区別しています。 awk
では、両方が行なえる演算子を備えており、実行時にどちらの比較
を行なうかを決定します。 a2p はこの演算子の動作について、完
Perl manpages Last change: LOCAL 1
A2P(1) USER COMMANDS A2P(1)
全な awk のエミュレーションを行なおうとはしません。 その代
わりに、どちらが必要かを推測します。 これは、大概は正しいも
のですが、だまされることもあります。 このような推測を行なっ
た場所には、"#???" というコメントでマークを付けてあります。
変換後にこのコメントがある場所を探して、チェックの必要がある
かもしれません。 一度は perl に -w スイッチを付けて実行して
見ると良いかもしれません。 もし、eq が必要なところで == を
使っていると、警告が出されます。
Perl は、存在しない配列要素を参照しただけで、存在するように
なるという awk の動作をエミュレートしようとしません。 その
後に続く、for ... in のために、何らかの形で、この機能に頼っ
ているとすれば、Perl では使えません。
a2p が、行の split の結果を ($Fld1, $Fld2, $Fld3, ...) のよ
うな変数のリストに代入する場合には、上に述べた -n オプション
を使って、a2p を再実行した方が良いかもしれません。 そうすれ
ば、スクリプト内で使用するフィールドに名前を付けることができ
ます。 ただ、split の結果を配列に代入しているときには、スク
リプトのどこかで、フィールドの数を参照しているかもしれません。
awk の exit 文は必ずしも exit するものではありません。 END
ブロックがあれば、そこへ飛ぶことになります。 END ブロックの
中で、そのような状況下のブロックを無視するために、おかしなこ
とをしている awk スクリプトは、END ブロックから、その条件を
取り除き、単に Perl スクリプトから抜けるようにすれば、簡単に
することができます。
Perl には、数値でインデクスする普通の配列と連想配列の 2 種類
の配列があります。 awk の配列は、通常連想配列に変換されます
が、インデクスが常に数値にしかならないということがわかれば、
{...} を [...] で書き換えることができます。 連想配列上の繰
り返しは、keys() 関数を使って行なわれますが、数値の配列での
繰り返しには、使いません。 問題の配列上で繰り返しを行なって
いるループは、書き換えの必要があるかもしれません。
awk では OFMT が当初 %.6g という値になっていると思っています
が、Perl は同様の意味を示す $# が %.20g という値になっている
と思っています。 OFMT のデフォルト値を使おうとするのであれ
ば、明示的に $# を設定する必要があります。
awk スクリプトでは、暗黙のうちに行なわれる split 演算が、変
換後のスクリプトのループの先頭近くにあります。 必要なときに
だけ split を行なうように、レコード全体に対する条件を調べた
後で、split を行なうように変更できる場合があります。
美的理由から、配列のベース $[ を 1 から、Perl のデフォルト
である 0 に戻したいと思うことがあると思いますが、すべての配
列の添字の他に、すべての substr() 演算や index() 演算のイン
デクスにも影響があることを忘れないでください。
Perl manpages Last change: LOCAL 2
A2P(1) USER COMMANDS A2P(1)
"# Here is a workaround because awk is dumb" というキュー
トなコメントは、変更されずに渡されます。
awk スクリプトは、シェルスクリプトに埋め込まれることも多く、
パイプを使って awk とやり取りをします。 多くの場合、このシ
ェルのラッパー自体を、Perl のスクリプトにしてしまうことがで
きます。 Perl は、自分自身で入出力のパイプをオープンできま
すし、awk が自分だけではできないことも、Perl は自分でできる
ことが多いからです。
特殊変数 RSTART や RLENGTH を参照しているスクリプトは、$`、
$&、$' といった変数が設定されたパターンマッチのスコープ内で
あれば、これらの変数を参照することで、簡単にすることができま
す。
生成された Perl スクリプトでは、awk の getline や print を正
確に扱うためのサブルーティンを定義している場合があります。
a2p では、通常、効率よりも正確さをとっていますので、多くの場
合、そういった意味を保つだけのコードを止めて書き直すことで、
効率的なものに書き直すことができます。
効率化のために、サブルーティンの最後で実行される return 文の
キーワード "return" を省きたい場合があります。 a2p は、多く
の共通的な場合を見つけますが、複雑な場合の込み入ったブロック
の解析は行ないません。
ARGV[0] は $ARGV0 に変換されますが、ARGV[n] は $ARGV[$n] に
変換されます。 ループで ARGV[0] を含めて繰り返しを行なって
いる場合には、うまくいきません。
ENVIRONMENT
a2p では、環境変数を使用しません。
AUTHOR
Larry Wall <lwall@jpl-devvax.Jpl.Nasa.Gov>
(訳注: 現在は <lwall@netlabs.com>)
FILES
SEE ALSO
perl perl コンパイラ/インタプリタ
s2p sed から perl へのトランスレータ
DIAGNOSTICS
BUGS
実行時に被演算子を調べて、文字操作か数値操作かを切り替えて、
awk の動作をエミュレートすることは可能ですが、それは、とても
大きく、非効率的なものとなるでしょう。 a2p の推察は、大概は
正しいものです。
awk の構文トリーのためのメモリは、現在スタティックにとってあ
り、これを使いきってしまう可能性があります。
Perl manpages Last change: LOCAL 3