富永研究室 ハンドブック プログラム言語

Awk言語

[Comp] [Class]   [Upper]


[参考文献] [関連情報]



■ awk言語の基本知識

● awk言語の経緯

awk言語は、UNIX上のテキストファイルを処理するためのスクリプト言語として開発された。 awkの名前の由来は、開発者であるV.Aho、P.J.Weinberger、B.W.Kernighanの3人の頭文字である。 awk言語の処理系は、バッチ処理型のインタプリタである。 現在では、いろいろな拡張が行われ、各種のマシン上に移植されている。 その1つとして有名なのが、 GNUと呼ばれる代表的なフリーソフトウェアの形態に属しているgawkである。 GNUは、 FSF[free-software foundation]という組織が管理しているフリーソフトウェアの総称である。 GNUには、GCC処理系やEmacsエディタをはじめとする質の高いソフトウェアが数多く属している。 jgawkは、gawkを田中良知(serow)氏が日本語化したものである。 本文では、gawk言語を前提として、説明している。

● 起動形式

○ > gawk  "スクリプト"                       ※ 以後、端末からの入力
○ > gawk  -f スクリプト名                    ※ 以後、端末からの入力
○ > gawk  "スクリプト"     テキスト名
○ > gawk  -f スクリプト名  テキスト名

● 起動時のオプション指定

○ スクリプト指定        -f  スクリプト名   
○ 変数値の設定          -v  変数名=値
○ 制御変数FSの設定      -F  区切りパターン(正規表現)
○ gawkの版数表示        -V  
○ GNUの著作権表示       -C
○ オプション指定の終了  --

● awk言語の強制終了

gawkの実行を強制的に終了させたいときは、^C とする。何回やっても駄目ならSTOPキーを押す。 それでも駄目ならリセットをかける。


■ スクリプトの全体構造

● スクリプトの形式

パターンとアクションの組を幾つか並べたものがawk言語のスクリプトである。 ただし、パターンおよびアクションの一方は省略できる。 また、補助的なスクリプトとして、ユーザによる関数定義も行える。 パターンとアクションの組は、スクリプトの実行時には、上から順に評価される。 関数定義は、どこに置いてもよい。特に、C言語と違い、後方参照になっても構わない。
○ パターン                   ※ パターンに照合するレコードを表示
○ { アクション }             ※ 各レコードに対してアクションを実行
○ パターン { アクション }    ※ パターンに照合するレコード毎にアクションを実行

○ function 関数定義          ※ スクリプトで共用する手続きの定義

● パターン部の形式

パターン同士を論理演算で組み合わせて複雑なパターン指定を行うこともできる。
○ /正規表現/                           ※ 正規表現に照合するとき
○ 演算式                               ※ 演算式の評価が0でないとき
○ BEGIN                                ※ データの入力開始前
○ END                                  ※ データの入力完了後
○ パターン1, パターン2                 ※ パターン間に挟まれる各レコード
○ パターン1 ? パターン2 : パターン3    ※ if ‥ then ‥ else ‥ 構造と同じ

● 関数定義

C言語の型宣言の代わりに function を置く。func でもよい。 関数呼出時に、後の方の引数を省略することができる。 そのため、適当なデフォルト値を定めておけば、オプション引数として扱える。 関数呼出時に使わない仮引数は、局所変数として用いることができる。
  function 関数名(仮引数, ‥) { 定義本体 }

● コメント

コメントとは、# 以降に書く。 これは、Cシェルスクリプトと同じである。 C言語の /* */ のように複数行を一括してコメントにする方法はない。
○ # コメント        ※ その行の以降の文字列をコメントとして無視する


■ アクション部の制御構文

● 順次制御

C言語と異なり、復帰改行すれば行末の連接記号 ; を省略できる。 連文の最後の ; も省略可能である。
○ 連接                文; 文       ※ 連続して実行する文の並び
○ ブロック化          { 連文 }     ※ 複数の文の連接を1つの文として扱う

● 終了制御

○ レコード処理の明示的終了    next         ※ 次のレコードを読み込んで処理(next文はawk言語特有)
○ 手続きの明示的終了          return 式    ※ 式の値は関数の返却値
○ プログラムの明示的終了      exit 式      ※ 式の値はプログラムの終了値(exit文はC言語と異なる形式)

● 分岐制御

分岐条件は、式の値が 0 または空列 "" のとき偽、 それ以外の値のとき真とみなされる。
○ 単分岐                if ( 分岐条件 ) { 真時処理 }
○ 双分岐                if ( 分岐条件 ) { 真時処理 } else { 偽時処理 }
○ 連分岐(単分岐直列)    if ( 分岐条件 ) { ‥ }; if ( 分岐条件 ) ‥
○ 多分岐(双分岐並列)    if ( 分岐条件 ) { ‥ } else if ( 分岐条件 ) ‥

● 反復制御

for ( 式1; 式2; 式3 ) { ‥ } は、 式1; while ( 式2 ) { ‥; 式3; } と同じ処理を行う。
○ 入口判定継続条件      while ( 継続条件 ) { 反復内容 }
○ 出口判定継続条件      do { 反復内容 } while ( 継続条件 )

○ 無条件反復            while ( 1 ) { 反復内容 }
要素列挙反復はawk言語に特有の構文である。
○ 構造的反復            for ( 初期化; 継続条件; 更新 ) { 反復内容 }
○ 要素列挙反復          for ( 変数 in 配列名 ) { 反復内容 }            
〔例〕 for ( k = 1; k <= n; k++ ) { ‥ }
       for ( k = 0; k < n; k++ ) { ‥ }
       for ( k = n; k >= 1; k-- ) { ‥ }
○ 反復からの局所脱出    break       ※ 一番内側の反復から強制的に抜ける
○ 反復の明示的更新      continue    ※ 一番内側の反復を明示的に次の回に進める


■ データ

● 基本データ型

C言語と違い、明示的な型宣言がない。変数の型は、文脈で判断される。
○ 数値型          文字列を数値に変えるには データ+0 とする
○ 文字列型        数値を文字列に変えるには データ "" とする

● データの表現

○ 整数        123  -2345           
○ 実数        1.0  -1.3e-23        ※ 数学的表記または理科的表記(有効数字6桁)
○ 文字列      "ab \"c\nd"          
○ 正規表現    /^a[0-5]+(\*|-)$/    ※ 照合演算などに使用

● 制御文字

\ で始まり、特別な意味を持つ。
○ 復帰改行[newline]           \n            
○ 同じ行の先頭へ復帰[return]  \r
○ 水平タブ[tabulation]        \t
○ 1文字分前に戻る[backspace]  \b
○ ビープ音[alert]             \a
○ 改ページ[formfeed]          \f            ※ emacs上での^Lと同じ

○ エスケープして普通の文字に  \'  \"  \\    ※ 区切り記号を普通の文字とする
○ ASCIIコード表示による文字   \x1a  \004    ※ \xで始まると16進数、他は8進数

● 名前

名前は、プログラム中で、変数・関数・配列などに付ける識別子のことである。 予約語と一致しないようにする。 英数字(大文字と小文字は区別)および下線(_)を用いる。 ただし、先頭は数字以外の文字とする。 最初の8文字が実際の識別に使われる。9文字目以降は区別されない。 変数は最初の使用時に "" に初期化される。数値と見るときは 0 に初期化される。

● 配列

配列の添字はどこから始めてもよい。 多次元配列は多重配列として記述し、累次配列であるC言語とは形式が異なる。 連想配列はawk言語特有である。
○ 一次元配列    配列名[位置]           ※ 位置は整数値
○ 多次元配列    配列名[成分, ‥]       ※ 成分は整数値
○ 連想配列      配列名[キー名]         ※ キー名は文字列
配列の使用時の宣言は必要ないが、不要になった配列は資源節約のため開放しておく。 これは、以前に使った配列を誤って参照する危険性を回避するためでもある。
○ 配列の開放    delete 配列名[添字]


■ 特別な意味を持つ変数

● コマンドライン入力を格納する変数

○ ARGC        コマンドライン引数の個数
○ ARGV[]      コマンドライン引数の値の配列(ARGV[0]はawkコマンド名)

● レコードおよびフィールドの指定

○ NR          現レコードの番号
○ NF          現レコードのフィールド数
○ $0          現レコードの全体
○ $n          現レコードのn番目のフィールド($1〜$NF)

● フィールドとレコードの区切り

RS に空列 "" を代入すると、空行が区切りとして指定されたことになる。
FS に長さ1の文字列を代入すると、その1文字自身を区切りとする。
○ RS          入力レコードの区切りパターン(デフォルトでは復帰改行 /\n/)
○ FS          入力フィールドの区切りパターン(デフォルトでは空白の並び /[ \t]+/)
○ ORS         出力レコードの区切り文字(デフォルトでは復帰改行 "\n")
○ OFS         出力フィールドの区切り文字(デフォルトでは空白1文字 " ")

● 関数 match() による照合で設定される変数

○ RSTART      照合した文字列の先頭の位置(半角単位) 
○ RLENGTH     照合した文字列の長さ(半角単位)

● 入力ファイルに関係する変数

○ FILENAME    現在の入力ファイル名
○ FNR         現在の入力ファイルでの現レコードの番号

● その他

○ OFMT        print文における数値の出力形式
○ SUBSEP      関数の引数および配列の多重添字の区切り文字(デフォルトでは",")
○ IGNORECASE  英字の大文字小文字の区別の有無(デフォルトでは区別有 1)
○ ENVIRON[]   環境変数名を添字とし、その値を要素として格納している配列


■ 演算式と代入

C言語とほぼ同じ構文である。

● 算術演算

C言語ではデータ型により実数商または整数商となるが、除算は常に実数商となる。 また、C言語と異なり、累乗演算 ^ が使える。
○ 加法    式 + 式
○ 減法    式 - 式
○ 乗法    式 * 式
○ 除法    式 / 式
○ 累乗    式 ^ 式
○ 剰余    式 % 式    

● 数学関数

○ int(x)         切捨て整数化    

○ sqrt(x)        平方根          
○ exp(x)         指数関数  
○ log(x)         対数関数     
○ sin(x)         正弦関数
○ cos(x)         余弦関数      
○ atan2(y, x)    逆正接値 arctan(y/x)

● 乱数

○ rand()         0〜1区間乱数    
○ srand(x)       xを種とする乱数の初期化    

● 変数への値の代入

代入値は代入式自身の値でもある。この場合、代入後に参照を行う。
○ 代入        変数名 = 式
               変数名1 = ‥ = 変数名n = 式    ※ 同時代入可能

● 自己代入

自己代入では、変数と式とに指定された演算を行った結果をその変数に再代入する。 更新代入を式の中で用いるときは、バグを生じやすいのでよく考えてからにする。 更新代入は、代入式の左辺の配列の添字中にも使うことができる。
○ 自己代入    式 += 式    式 -= 式
               式 *= 式    式 ^= 式
               式 /= 式    式 %= 式

○ 後置更新代入    式++  式--                     ※ 値を参照した後に更新 
○ 前置更新代入    ++式  --式                     ※ 先に値を更新してから参照

● 数値比較演算

○ 等号/不等号    式 == 式    式 != 式
○ 大小比較       式 <  式    式 >  式    式 <= 式    式 >= 式

● 論理演算

0 または空列 "" を偽とみなし、それ以外の値を真とみなす。 演算の結果としては、真の場合 1 を、偽の場合 0 を返す。
○ 連言(かつ)      式 && 式    ※ 前から順に評価
○ 選言(または)    式 || 式    ※ 前から順に評価 
○ 否定(でない)    ! 式        


■ 文字と文字列

● ASCIIコード

8ビットで表される文字を1バイト文字という。 実際には、先頭ビットは常に0とし、残りの7ビットで以下の128種類の文字を表す。

● 文字列演算

○ 連結            式 式       ※ 空白を演算子とし、文字列をその順序で連結

● 文字列比較

大小比較は、文字コードによる辞書式順序による。 照合/非照合における右辺は正規表現と解釈される。右辺は /正規表現/ でもよい。
○ 等号/不等号    式 == 式    式 != 式
○ 大小比較       式 <  式    式 >  式    式 <= 式    式 >= 式
○ 照合/非照合    式  ~ 式    式 !~ 式 


■ 正規表現

● 正規表現の演算子

○ 連結        AB      ※ Aの後にBを続けた文字列
○ 括弧        (A)      ※ Aと同じ文字列(Aを1まとまりにする)

○ 選択        A|B     ※ AまたはB
○ 単選択      A?       ※ Aの0回または1回の出現(空列を含む)

○ 閉包        A*       ※ Aの0回以上の繰返し(空列を含む)
○ 正閉包      A+       ※ Aの1回以上の繰返し(空列を含まない)

○ 先頭位置    ^A       ※ Aから始まる文字列
○ 末尾位置    A$       ※ Aで終わる文字列

● 1文字指定の方法

○ 文字自身      文字           ※ その文字自身
○ 制御文字      \文字名        ※ そのままでは表示できない文字
○ エスケープ    \文字          ※ 正規表現の演算記号を普通の文字とみなす
○ 任意文字      .              ※ 復帰改行を除く任意の半角1文字
○ 列挙          [文字 ‥]      ※ 列挙された1文字を選択
○ 範囲の指定    [文字-文字]    ※ 文字コード順で範囲内の1文字を選択
○ 範囲の除外    [^文字 ‥]     ※ 列挙された文字以外の1文字を選択

● 注意が必要な文字

以下の文字は、awk言語の正規表現を使う上で、特別な意味を持っている。 単なる文字として扱うには、エスケープしておく必要がある。
○ コマンドライン    "  '  <  >  |  \  
○ スクリプト        "  /  \
○ 正規表現          (  )  |  ?  *  +  ^  $  .  \  
○ 範囲指定          [  ]  ^  -  \

● 主な文字範囲

○ 半角文字      [ -~]
○ 全角記号      [、-◯]
○ 数字          [0-9]         [0-9]
○ 英字          [A-Za-z]      [A-Za-z]
○ 仮名          [ぁ-ん]       [ァ-ンヴヵヶー]
○ ギリシャ文字  [Α-Ωα-ω]
○ ロシア文字    [А-Яа-я]
○ 罫線          [─-╂]
○ 漢字          [亜-腕]       [弌-熙]


■ 文字列操作関数

awk言語特有のものが多いので注意する。 jgawkなど、日本語対応版では、全角文字にも対応する関数が追加されている。

● 文字列長

引数を省略し、変数のように使える。 lengthおよびjlengthで$0の長さを表す。
○ length(STR)               文字列STRの長さ(半角単位)を返す
○ jlength(STR)              文字列STRの長さ(全角対応)を返す

● 部分列の位置

部分列が存在しない場合は0を返す。
○ index(STR, SUB)           文字列STR中の部分列SUBの先頭位置(半角単位)を返す
○ jindex(STR, SUB)          文字列STR中の部分列SUBの先頭位置(全角対応)を返す

● 指定位置の部分列

LENを省略すると文字列の最後までを切り出す。
○ substr(STR, POS, LEN)     文字列STRのPOS位置から長さLENの部分列(半角単位)を返す
○ jsubstr(STR, POS, LEN)    文字列STRのPOS位置から長さLENの部分列(全角対応)を返す

● 文字種変換

C言語と異なり、文字列の変換である。
○ tolower(STR)              文字列STRの英大文字を英小文字に置換した文字列を返す
○ toupper(STR)              文字列STRの英小文字を英大文字に置換した文字列を返す

● 文字列照合

関数の返却値と副作用の両方に注意する。
○ match(STR, REG)           文字列STR中で正規表現REGに照合する先頭位置を返す

● 文字列置換

関数の返却値と副作用の両方に注意する。
○ sub(REG, NEW, VAR)          最左最長な照合列のみを置換し、置換回数(0または1)を返す
○ gsub(REG, NEW, VAR)         文字列の先頭から最長な照合列を順次置換し、置換回数を返す

● 文字列分割

関数の返却値と副作用の両方に注意する。
○ split(STR, ARR, REG)        分割個数を返す

● 文字列整形

C言語と異なる形式である。 str = sprintf("%4d", num) のように使う。
○ sprintf(出力書式, 式, ‥)    printf()文と同様の出力形式に整形された文字列を返す


■ 入力

リダイレクトおよびパイプラインと組み合わせて使用できる。

● ファイル入力

○ getline                            ※ 現入力ファイルから現レコード1つを$0に入力
○ getline 変数名                     ※ 現入力ファイルから現レコード1つを変数に入力

○ getline < ファイル名               ※ 指定ファイルから現レコード1つを$0に入力
○ getline 変数名 < ファイル名        ※ 指定ファイルから現レコード1つを変数に入力

○ getline < "con"                    ※ 標準入力から1行分を$0に入力
○ getline 変数名 < "con"             ※ 標準入力から1行分を変数に入力

● パイプライン入力

コマンドの実行結果から最初の1行を取り出して読み込む。 コマンド実行結果はオープン状態になり、 同じコマンドの参照毎に現レコード位置が更新される。 変数名を指定しないと$0に格納され、$n や NF の値も新しく設定される。
○ コマンド | getline                 ※ コマンドの実行結果から現レコード1つを$0に入力 
○ コマンド | getline 変数名          ※ コマンドの実行結果から現レコード1つを変数に入力 


■ 出力

リダイレクトおよびパイプラインと組み合わせて使用できる。

● 簡易出力

awk言語に特有である。
○ print 式1, ‥ , 式n                        ※ 標準出力(ディスプレイ)への出力
○ print 式1, ‥ , 式n >  出力ファイル        ※ ファイルへの新規出力
○ print 式1, ‥ , 式n >> 出力ファイル        ※ ファイルへの追加出力
○ print 式1, ‥ , 式n |  コマンド            ※ コマンドへの引数として渡される
  • 括弧を付けてprintf文風に print(式, ‥) としてもよい。
  • それぞれの式の値の表示の区切りは、変数OFSで設定された文字列になる。

    ● 書式付出力

    C言語と異なり, 括弧を付けないprint文風に printf 書式, 式, ‥ としてもよい。
    ○ printf(出力書式, 式1, ‥ , 式n)                        ※ 標準出力(ディスプレイ)への出力
    ○ printf(出力書式, 式1, ‥ , 式n) >  出力ファイル        ※ ファイルへの新規出力
    ○ printf(出力書式, 式1, ‥ , 式n) >> 出力ファイル        ※ ファイルへの追加出力
    ○ printf(出力書式, 式1, ‥ , 式n) |  コマンド            ※ コマンドへの引数として渡される
    

    ● 書式指定子

    ○ 10進数(整数)            %d    
    ○ 8進数(整数)             %o    
    ○ 16進数(整数)            %x    ※ %X にするとa〜fを大文字A〜Fで表示
    
    ○ 文字                    %c    
    ○ 文字列                  %s    
    
    ○ 数学的表記(実数)        %f    ※ 整数部.小数部 の形式
    ○ 理科的表記(実数)        %e    ※ 仮数部e指数部 の形式
    ○ %eと%fの短い方          %g    
    
    ○ %の表示                 %%
    

    ● 書式指定子の修飾子

    ○ 表示幅の確保(右詰め)     %数d
    ○ 右詰めし、左側に0を補充  %0数d
    ○ 左詰め                   %-数d
    
    ○ 表示幅の確保(右詰め)     %数f
    ○ 小数点以下の表示桁数     %.数f
    ○ 左詰め                   %-数f
    
    ○ 表示幅の確保             %数s
    ○ 文字列の表示字数         %.数s
    ○ 左詰め                   %-数s
    

    ● 色指定

    ○ \033[色番号m    ※ 以降の文字列が番号で指定された色に変わって表示される
    
    30 黒色    34 青色    40 黒色反転    44 青色反転
    31 赤色    35 紫色    41 赤色反転    45 紫色反転
    32 緑色    36 水色    42 緑色反転    46 水色反転
    33 黄色    37 白色    43 黄色反転    47 白色反転
    
    PC98の場合である。DOS/Vなど他の機種では少し異なる。
    0 ノーマル          4 アンダーライン    
    1 ハイライト        5 ブリンク          
    2                   6                   
    3                   7 リバース          
                        8 シークレット      
    


    ■ 外部インタフェース

    ● システム制御

    awkだけでは対処し切れない処理は、外部コマンドを起動して解決する。 文字列として解釈されるので、ディレクトリの区切りは、 "\\" としなければならない。 外部コマンドのエラーによっては、gawk自身の実行もエラー終了になってしまう。
    ○ system(COM)    文字列COMで指定されるコマンドの実行
    
    〔例〕 system("dir ..\\work");
    

    ● ファイルのクローズ

    オープンしたファイルはクローズしなければ、新たにアクセスできない。
    ○ close(FILE)     文字列 FILE で指定されるファイルをクローズする
    ○ close(COM)      既に文字列 COM でオープンしたパイプラインやコマンドをクローズする
    

    ● ファイル指定

    ○ 標準入力          /dev/stdin
    ○ 標準出力          /dev/stdout
    ○ 標準エラー出力    /dev/stderr
    ○ ファイル記述子    /dev/fd/番号
    
    ○ MS-DOS端末        con               
    ○ UNIX端末          /dev/tty
    

    ● パイプラインとリダイレクト

    awkスクリプトの実行結果をファイルに出力することができる。 awkスクリプトと他のMSコマンドを組み合わせてフィルタ処理を行うことができる。
    ○ コマンド  >   ファイル         ※ 指定ファイルへの新規出力(リダイレクト)
    ○ コマンド  >>  ファイル         ※ 指定ファイルへの追加出力(リダイレクト)
    
    ○ コマンド1  |  コマンド2        ※ コマンド1の実行結果をコマンド2の引数として渡す(パイプライン)
    
    〔例〕 > type gawk.man | more
    

    ● awkスクリプトの検索パス

    環境変数 AWKPATH でawkスクリプトの検索パスを指定することができる。 パスの通ったディレクトリ内のスクリプトを実行するときは、 ファイル名を指定するだけでよい。 始めのほうに書かれたディレクトリを先に検索する。 現ディレクトリをまず検索するように、パスの最初は "." にする。
    ○ set AWKPATH = .;ディレクトリ;‥
    


    ★ 文字コード表

    ┏━━┳━━┳━━┳━━┓┏━━┳━━┳━━┳━━┓┏━━┳━━┳━━┳━━┓┏━━┳━━┳━━┳━━┓
    ┃文字┃10進┃ 8進┃16進┃┃文字┃10進┃ 8進┃16進┃┃文字┃10進┃ 8進┃16進┃┃文字┃10進┃ 8進┃16進┃
    ┣━━╋━━╋━━╋━━┫┣━━╋━━╋━━╋━━┫┣━━╋━━╋━━╋━━┫┣━━╋━━╋━━╋━━┫
    ┃ NUL┃   0┃ 000┃ 00 ┃┃ SP ┃  32┃ 040┃ 20 ┃┃  @ ┃  64┃ 100┃ 40 ┃┃  ` ┃  96┃ 140┃ 60 ┃
    ┃ SOH┃   1┃ 001┃ 01 ┃┃  ! ┃  33┃ 041┃ 21 ┃┃  A ┃  65┃ 101┃ 41 ┃┃  a ┃  97┃ 141┃ 61 ┃
    ┃ STX┃   2┃ 002┃ 02 ┃┃  " ┃  34┃ 042┃ 22 ┃┃  B ┃  66┃ 102┃ 42 ┃┃  b ┃  98┃ 142┃ 62 ┃
    ┃ ETX┃   3┃ 003┃ 03 ┃┃  # ┃  35┃ 043┃ 23 ┃┃  C ┃  67┃ 103┃ 43 ┃┃  c ┃  99┃ 143┃ 63 ┃
    ┃ EOT┃   4┃ 004┃ 04 ┃┃  $ ┃  36┃ 044┃ 24 ┃┃  D ┃  68┃ 104┃ 44 ┃┃  d ┃ 100┃ 144┃ 64 ┃
    ┃ ENQ┃   5┃ 005┃ 05 ┃┃  % ┃  37┃ 045┃ 25 ┃┃  E ┃  69┃ 105┃ 45 ┃┃  e ┃ 101┃ 145┃ 65 ┃
    ┃ ACK┃   6┃ 006┃ 06 ┃┃  & ┃  38┃ 046┃ 26 ┃┃  F ┃  70┃ 106┃ 46 ┃┃  f ┃ 102┃ 146┃ 66 ┃
    ┃ BEL┃   7┃ 007┃ 07 ┃┃  ' ┃  39┃ 047┃ 27 ┃┃  G ┃  71┃ 107┃ 47 ┃┃  g ┃ 103┃ 147┃ 67 ┃
    ┣━━╋━━╋━━╋━━┫┣━━╋━━╋━━╋━━┫┣━━╋━━╋━━╋━━┫┣━━╋━━╋━━╋━━┫
    ┃ BS ┃   8┃ 010┃ 08 ┃┃  ( ┃  40┃ 050┃ 28 ┃┃  H ┃  72┃ 110┃ 48 ┃┃  h ┃ 104┃ 150┃ 68 ┃
    ┃ HT ┃   9┃ 011┃ 09 ┃┃  ) ┃  41┃ 051┃ 29 ┃┃  I ┃  73┃ 111┃ 49 ┃┃  i ┃ 105┃ 151┃ 69 ┃
    ┃ LF ┃  10┃ 012┃ 0A ┃┃  * ┃  42┃ 052┃ 2A ┃┃  J ┃  74┃ 112┃ 4A ┃┃  j ┃ 106┃ 152┃ 6A ┃
    ┃ VT ┃  11┃ 013┃ 0B ┃┃  + ┃  43┃ 053┃ 2B ┃┃  K ┃  75┃ 113┃ 4B ┃┃  k ┃ 107┃ 153┃ 6B ┃
    ┃ FF ┃  12┃ 014┃ 0C ┃┃  , ┃  44┃ 054┃ 2C ┃┃  L ┃  76┃ 114┃ 4C ┃┃  l ┃ 108┃ 154┃ 6C ┃
    ┃ CR ┃  13┃ 015┃ 0D ┃┃  - ┃  45┃ 055┃ 2D ┃┃  M ┃  77┃ 115┃ 4D ┃┃  m ┃ 109┃ 155┃ 6D ┃
    ┃ SO ┃  14┃ 016┃ 0E ┃┃  . ┃  46┃ 056┃ 2E ┃┃  N ┃  78┃ 116┃ 4E ┃┃  n ┃ 110┃ 156┃ 6E ┃
    ┃ SI ┃  15┃ 017┃ 0F ┃┃  / ┃  47┃ 057┃ 2F ┃┃  O ┃  79┃ 117┃ 4F ┃┃  o ┃ 111┃ 157┃ 6F ┃
    ┣━━╋━━╋━━╋━━┫┣━━╋━━╋━━╋━━┫┣━━╋━━╋━━╋━━┫┣━━╋━━╋━━╋━━┫
    ┃ DLE┃  16┃ 020┃ 10 ┃┃  0 ┃  48┃ 060┃ 30 ┃┃  P ┃  80┃ 120┃ 50 ┃┃  p ┃ 112┃ 160┃ 70 ┃
    ┃ DC1┃  17┃ 021┃ 11 ┃┃  1 ┃  49┃ 061┃ 31 ┃┃  Q ┃  81┃ 121┃ 51 ┃┃  q ┃ 113┃ 161┃ 71 ┃
    ┃ DC2┃  18┃ 022┃ 12 ┃┃  2 ┃  50┃ 062┃ 32 ┃┃  R ┃  82┃ 122┃ 52 ┃┃  r ┃ 114┃ 162┃ 72 ┃
    ┃ DC3┃  19┃ 023┃ 13 ┃┃  3 ┃  51┃ 063┃ 33 ┃┃  S ┃  83┃ 123┃ 53 ┃┃  s ┃ 115┃ 163┃ 73 ┃
    ┃ DC4┃  20┃ 024┃ 14 ┃┃  4 ┃  52┃ 064┃ 34 ┃┃  T ┃  84┃ 124┃ 54 ┃┃  t ┃ 116┃ 164┃ 74 ┃
    ┃ NAK┃  21┃ 025┃ 15 ┃┃  5 ┃  53┃ 065┃ 35 ┃┃  U ┃  85┃ 125┃ 55 ┃┃  u ┃ 117┃ 165┃ 75 ┃
    ┃ SYN┃  22┃ 026┃ 16 ┃┃  6 ┃  54┃ 066┃ 36 ┃┃  V ┃  86┃ 126┃ 56 ┃┃  v ┃ 118┃ 166┃ 76 ┃
    ┃ ETB┃  23┃ 027┃ 17 ┃┃  7 ┃  55┃ 067┃ 37 ┃┃  W ┃  87┃ 127┃ 57 ┃┃  w ┃ 119┃ 167┃ 77 ┃
    ┣━━╋━━╋━━╋━━┫┣━━╋━━╋━━╋━━┫┣━━╋━━╋━━╋━━┫┣━━╋━━╋━━╋━━┫
    ┃ CAN┃  24┃ 030┃ 18 ┃┃  8 ┃  56┃ 070┃ 38 ┃┃  X ┃  88┃ 130┃ 58 ┃┃  x ┃ 120┃ 170┃ 78 ┃
    ┃ EM ┃  25┃ 031┃ 19 ┃┃  9 ┃  57┃ 071┃ 39 ┃┃  Y ┃  89┃ 131┃ 59 ┃┃  y ┃ 121┃ 171┃ 79 ┃
    ┃ SUB┃  26┃ 032┃ 1A ┃┃  : ┃  58┃ 072┃ 3A ┃┃  Z ┃  90┃ 132┃ 5A ┃┃  z ┃ 122┃ 172┃ 7A ┃
    ┃ ESC┃  27┃ 033┃ 1B ┃┃  ; ┃  59┃ 073┃ 3B ┃┃  [ ┃  91┃ 133┃ 5B ┃┃  { ┃ 123┃ 173┃ 7B ┃
    ┃ FS ┃  28┃ 034┃ 1C ┃┃  < ┃  60┃ 074┃ 3C ┃┃  \ ┃  92┃ 134┃ 5C ┃┃  | ┃ 124┃ 174┃ 7C ┃
    ┃ GS ┃  29┃ 035┃ 1D ┃┃  = ┃  61┃ 075┃ 3D ┃┃  ] ┃  93┃ 135┃ 5D ┃┃  } ┃ 125┃ 175┃ 7D ┃
    ┃ RS ┃  30┃ 036┃ 1E ┃┃  > ┃  62┃ 076┃ 3E ┃┃  ^ ┃  94┃ 136┃ 5E ┃┃  ~ ┃ 126┃ 176┃ 7E ┃
    ┃ US ┃  31┃ 037┃ 1F ┃┃  ? ┃  63┃ 077┃ 3F ┃┃  _ ┃  95┃ 137┃ 5F ┃┃ DEL┃ 127┃ 177┃ 7F ┃
    ┗━━┻━━┻━━┻━━┛┗━━┻━━┻━━┻━━┛┗━━┻━━┻━━┻━━┛┗━━┻━━┻━━┻━━┛