文字列を # で囲む

与えられた文字列を、#で囲むプログラム - みずぴー日記 にインスパイヤされて同じように関数で処理してみます。 ただし、awk の場合には多値を扱えないため、配列のようなものを返すのには注意が必要です。 ここでは SUBSEP を区切りとする文字列を返していくことで実現させています。

#! /usr/local/bin/gawk -f
# border.awk
# 文字列を # で囲む
# usage: gawk -f border.awk str[s]

BEGIN {
    for (i = 1; i < ARGC; i++) {
        msg[i] = ARGV[i];
    }

    print show(border("#", margin(1, centerAlign(msg))));
}

# show():   表示するためのメソッドのような気もするけど実際には SUBSEP を
#           改行に置換するだけ
#   in:     文字列 str
#   out:    SUBSEP を改行にした文字列
function show(str) {
    gsub(SUBSEP, "\n", str);

    return str;
}

# border():     文字列 str1 で囲まれた文字列を作る
#   in:         囲むために使う文字 str1
#               囲まれる文字列 str2
#   out:        文字列 str1 で囲まれた文字列
function border(str1, str2) {
    split(str2, arr, SUBSEP);
    str2 = repeat_str(str1, length(arr[1])) SUBSEP \
           repeat_str(" ", length(arr[1])) SUBSEP \
           str2 SUBSEP \
           repeat_str(" ", length(arr[1])) SUBSEP \
           repeat_str(str1, length(arr[1]));

    sub(/^/, str1, str2);
    sub(/$/, str1, str2);
    gsub(SUBSEP, str1 SUBSEP str1, str2);

    return str2;
}

# margin():     文字列の回りにスペースを num 個入れる
#   in:     スペースの個数 num
#           文字列 str (実際には SUBSEP で区切られた配列)
#   out:    文字列の回りにスペースを num 個入れられた文字列
function margin(num, str,   i, new_str) {
    split(str, arr, SUBSEP);

    for (i = 1; i <= length(arr); i++) {
        new_str = new_str SUBSEP \
                  repeat_str(" ", num) arr[i] repeat_str(" ", num);
    }
    sub(SUBSEP, "", new_str);

    return new_str;
}

# centerAlign():    配列 arr のもっとも長い文字列に合わせてセンタリングする
#   in:     配列 arr
#   out:    文字列 str (多値が扱えないので SUBSEP で区切られた配列)
function centerAlign(arr,   i, max_length, count, str) {

    for (i = 1; i <= length(arr); i++) {
        if (max_length < length(arr[i])) {
            max_length = length(arr[i]);
        }
    }

    for (i = 1; i <= length(arr); i++) {
        while (length(arr[i]) < max_length) {
            count++;
            if (count % 2 == 1) {
                arr[i] = " " arr[i];
            } else {
                arr[i] = arr[i] " ";
            }
        }
    }

    for (i = 1; i <= length(arr); i++) {
        str = str SUBSEP arr[i];
    }
    sub(SUBSEP, "", str);

    return str;
}

# repeat_str():     文字列 str を数値 num 回繰り返す
#   in:     文字列 str
#           数値 num
#   out:    文字列 str を数値 num 回繰り返した文字列
function repeat_str(str, num,   i, result) {
    for (i = 1; i <= num; i++) {
        result = result str;
    }
    return result;
}

与えられた文字列を、#で囲むプログラム - みずぴー日記 の Python のプログラムと比較するとかなり長くなっているのが分かると思いますが、map() のようなものがないことと文字列の連接が大きく異なっている原因になっているのが分かります。

実行結果は同じようになるはずです。

$ gawk -f border.awk 1st "HELO WORLD"
##############
#            #
#     1st    #
# HELO WORLD #
#            #
##############

プログラムとしてはもっと簡略化できると思います。

tag_gawk.pngtag_gawk.png