2010年8月17日火曜日

文字列操作関数使用時の注意点まとめ - AWK

AWKの文字列操作関数と関連機能

**** 処理系共通の注意点
o 「\」は、特殊文字を書く為のキーワードです。(例。「\n」は改行コード)
   + 文字列の中に「\」を含めたい時は、「\\」と書きます。
   + 但し、Gawkの gensub 関数を使う時は、「\\数字」が意味を持つ場所もありますので、注意します。
o 特定の関数で、「&」が特別な意味を持つ場所があります。(gsub / sub
   + 「&」が特別な意味を持つ場所で「&」を含めたい時は、「\\&」と書きます。

o gsub 関数は、対象文字列の途中に改行コードが含まれていると、改行コード以降は置き換えないみたいです。
   + 少なくとも、正規表現の「^」(= チルダ)は文字列の先頭のみを置き換えます。
o split 関数の区切り文字で「\」自身を指定する時、"[\\]" と書く事は出来ません。
   + "[\\\\]" もしくは "\\" や "\\\\" を使います。

o 実数を文字列操作関数に渡すと、本処理の前に、7桁目を丸める傾向がありました。
   + 変換する桁数を簡単に増やしたい時は、変数CONVFMTを使います。
   + もしくは、sprintfを使って、特定の変数だけ有効桁数を変える事も出来ます。
   + 詳しくは、「数値から文字列にする時に、実数を7桁以上表示させる方法
o 文字列比較などの場面で、値を数値だと認識されてしまった時は、文字列化する必要があります。
   + 「v = v ""」のように、空文字を並べて書く方法
   + sprintf関数を使う方法
   + 7桁以上の実数を表示したい時は、「数値から文字列にする時に、実数を7桁以上表示させる方法

o 漢字などの全角文字で原因不明のエラーになる場合
   + 最初に、文法誤りの可能性を疑います。
   + 多くの場合、AWKプログラムと入力ファイルの文字コードを適切にすると、解決します。
      + Windows版のmawkとオリジナルは、Shift-JIS以外は対応していません。
   + Gawkの場合、システムの言語設定を一時的に合わせる方法もあります。
      + Gawk on Windowsの場合は、オプションで設定する事が出来ます。
      + Windowsとは関係がありませんが、UNIXの言語設定について
         + 現在の言語設定を確認する方法は「locale = UNIXで地域設定(ロケール)について確認する方法
         + UNIXの場合、ウィンドウ1つに対して言語設定を変更する事が出来ます。
   + 16進数などの特殊文字を使って表現すると、回避出来る事があります。
   + 文字コードを自動判定するような処理系の場合は、コメントで回避出来るかもしれません。
      + 例えば、Shift-JISの場合は、# あいうえお を最初の方に入れるなど
      + これは、古いブラウザーに対する文字化け回避の手法です。文字コード特有の文字を入れる事で、誤判定を防ぐ効果があります。
--------
# あいうえお
BEGIN {
  print "テストです。";
}
--------



**** 特定の処理系に関する注意点
** Gawk系特有の動作
o Gawk on Windows (3.1.7)で測定した所、sprintfの動作が、mawkや下の方法の9倍程度遅かったです。測定結果は「速度比較。文字列の組み立て
   + 動作が遅いと思ったら、文字列(と数値)の連結を、文字列などを並べる方法に変えてみると、改善するかもしれません。間に半角空白を入れます。
--------
BEGIN {
  n = 39;
  name = "ミク";
  v = n "番の" name "さん。";
  # Gawkの場合、次の文よりもn倍速いです。v = sprintf("%d番の%sさん", n, name);

  print v;
}
--------


o この他、UTF-8ファイルの読み込み1行目で、文字列操作関数の返す値が変な時は、UNICODE特有の見えない文字(BOM)が悪さをしているかもしれません。詳しくは「GawkでUTF-8のファイルを読み込む時の注意点

** mawk系特有の動作
o 全角文字の場合、文字数をバイト数で数えます。
o Mawk for Windowsについては、全角文字に対応していない関数があります。(sub / gsub / toupperなど)
   + 例えば、「表」を「\\」(= \の事です)で検索すると、「表」の後半部分で一致します。

** オリジナルAWK特有の動作
o 全角文字の場合、文字数をバイト数で数えます。
o 処理系自体が、日本語に対応していないみたいです。
   + 例えば、v = "表ミクさん表表"; print v; で文字化けします。


==
関連ページ:
    ▼AWKの文字列操作関数と関連機能▼ABC順
    ▼AWKプログラムを書く▼ABC順
    ▼AWK
    ▼制作メモ
    > 文字列を組み立てる
    文字列から文字を1つずつ取り出す
    文字列中で使用出来る特殊文字
    +
    配列を使う時の注意点まとめ
(2011年8月22日追加。split関数の区切り文字に「\」を指定する方法)
(2010年10月28日追加。文字コードを自動判定する処理系が誤判定する時の回避案)
(2010年10月22日追加。特殊文字へのリンクと、全角文字でエラーになった時)
(2010年8月23日追加。「\」と「&」)