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