ls を作ってみる

某所で ls に関する話題が出たので、つい awk で ls を作ってみました。 gawk には filefuncs という共有オフジェクトがあり、これをロードすることでファイル情報を取得できることから、ls -l のようなものを作ってみます。 この filefuncs を使うことでファイルの情報を簡単かつ高速に取得することができます。

ただし、UID と GID のままでも良いのですが、ここでは /etc/passwd と /etc/group からユーザー名とグループ名を見てます。

実際のコードは以下のようになります。

#! /bin/gawk -f
# ls.awk

@load "filefuncs"

BEGIN {

    passwd  = "/etc/passwd";
    group   = "/etc/group";

    FS = ":";

    while (getline < passwd > 0) {
        user_of[$3] = $1;
    }
    close(passwd);

    while (getline < group > 0) {
        group_of[$3] = $1;
    }
    close(group);

    for (i = 1; i <= ARGC - 1; i++) {
        stat(ARGV[i], stat_data_of);

        m_time = strftime("%Y-%m-%d %H:%M", stat_data_of["mtime"]);

        printf("%s %3d %8s %8s %9d %s %s\n",
            stat_data_of["pmode"],
            stat_data_of["nlink"],
            user_of[stat_data_of["uid"]],
            group_of[stat_data_of["gid"]],
            stat_data_of["size"],
            m_time,
            stat_data_of["name"]);
    }
}

外部コマンドを参照しないで作れるのは良いですね。

では、実行してみますが、必ず引数としてファイル名は必要です。

$ gawk -f ls_l.awk *
-rw-r--r--   1 hi_saito hi_saito       606 2011-06-06 09:38 ls.awk
-rw-r--r--   1 hi_saito hi_saito       606 2011-06-06 09:38 ls.awk~
-rw-r--r--   1 hi_saito hi_saito       878 2013-11-12 22:28 ls_l.awk
-rw-r--r--   1 hi_saito hi_saito       612 2013-11-12 22:22 ls_l.awk~

こんな感じで取得するこtができます。

ちなみにこれは ls の long-iso フォーマットなので、

$ ls -l --time-style=long-iso *
-rw-r--r--. 1 hi_saito hi_saito 606 2011-06-06 09:38 ls.awk
-rw-r--r--. 1 hi_saito hi_saito 606 2011-06-06 09:38 ls.awk~
-rw-r--r--  1 hi_saito hi_saito 878 2013-11-12 22:28 ls_l.awk
-rw-r--r--  1 hi_saito hi_saito 612 2013-11-12 22:22 ls_l.awk~

と、ls に近いフォーマットになっています。

tag_gawk.png