背景:
阅读文章

一个搜索指令

[日期:2007-05-11] 来源:  作者: [字体: ]

// find.c
// By jjgod for FYTX.

#include
#define itoa(x) sprintf("%d",x)

inherit F_CLEAN_UP;

void create() { seteuid(getuid()); }

public void search_dir(object me, string file, string dir, int raw);


public void search_in_file(object me, string info, string file);
public string *search_file(string file, string *flist, object me, int raw);
public string *deep_file_list(string dir);

int main(object me, string arg)
{
        string file, dir, flag;
        int raw;
       
        // 权限检查,需要安全系统支持
        if (! SECURITY_D->valid_grant(me, "(arch)"))
                return 0;
               
        if (! arg)
                return notify_fail("指令格式:find <文件名|内容> in <目录名|文
件名> [-c]\n");

        if (sscanf(arg, "%s in %s %s", file, dir, flag) != 3)
        {
                if (sscanf(arg, "%s in %s", file, dir) != 2)
                        notify_fail("指令格式:find <文件名|内容> in <目录名|文
件名> [-c]\n");
        }

        // 如果是查找包含内容模式
        if (flag == "-c") raw = 1;

        dir = resolve_path(me->query("cwd"), dir);
       
        seteuid(getuid(me));
       
        // 如果是在文件中查找模式
        if (file_size(dir) >= 0)
        {
                search_in_file(me, file, dir);
                return 1;
        }
       
        if (file_size(dir) == -2 && dir[strlen(dir) - 1] != '/') dir += "/";

        if (file_size(dir) != -2)
                return notify_fail(dir + " 并不是一个目录。\n");
       
        // 给一点提示,因为玩家可能会过于迟滞
        message_system("系统进行数据处理中,请耐心等候...");
       
        search_dir(me, file, dir, raw);
        return 1;
}

void search_dir(object me, string file, string dir, int raw)
{
        int i;
        string *flist, *result;
        string info, file_info, size;
       
        // 获得所有的深层目录文件列表
        flist = deep_file_list(dir);
       
        if (! arrayp(flist) || ! sizeof(flist))
        {
                message_system("系统数据处理完毕,请继续游戏。\n" ESC + "[K");

                info = HIR "文件搜索完毕:\n\n" NOR ESC + "[K"
                       HIR "目录" + dir + " 下并没有可供查找的文件。" NOR;
               
                message("system", info, me);
                return;
        }

        result = search_file(file, flist, me, raw);
       
        message_system("系统数据处理完毕,请继续游戏。\n" ESC + "[K");
               
        if (! sizeof(result))
                info = HIR "文件搜索完毕:\n" + ESC + "[K" + "\n" NOR ESC + "[
K"
                       HIR "目录 " + dir + " 下没有找到任何符合要求的文件。\n"
NOR
                       ESC + "[K";

        else
        {
                file_info = "";
                for (i = 0; i < sizeof(result); i++)
                {
                        if (eval_cost() < 100) set_eval_limit(0);
                       
                        size = itoa(file_size(result[i]) / 1000);
                        file_info += sprintf(CYN "%-45s " WHT "%4s " CYN " %s\
n",
                                             result[i],
                                             (size == "0" ? itoa(file_size(res
ult[i])) + "b" : size + "k"),
                                             CHINESE_D->chinese_time(9, ctime(
stat(result[i])[1])), );
                }
               
                info = HIR "文件搜索完毕:\n" + ESC + "[K" + "\n" NOR ESC + "[
K" +
                       file_info + NOR + ESC + "[K"
                       HIR "\n一共找到 " + sizeof(result) + " 个文件。" + ESC
+ "[K" + NOR
                       ESC + "[K\n" + ESC + "[K";
        }
       
        if (me)
                me->start_more(info);
//              message("system", info, me);
}

string *deep_file_list(string dir)
{
        int i;
        string *flist, *result = ({ }), file;
       
        flist = get_dir(dir);
       
        for (i = 0; i < sizeof(flist); i++)
        {
                file = dir + flist[i];
               
                if (file_size(file + "/") == -2)
                        result += deep_file_list(file + "/");
                else
                        result += ({ file });
        }
       
        return result;
}

string *search_file(string file, string *flist, object me, int raw)
{
        int i, j;
        string *result = ({ }), file_info;

        for (i = 0; i < sizeof(flist); i++)
        {
                if (raw == 0)
                {
                        j = strsrch(flist[i], "/", -1);
                        file_info = flist[i][j..(sizeof(flist[i]) - 1)];
               
                        if (file_info == file)
                        {
                                result += ({ flist[i] });
                                continue;
                        }
                        if (strsrch(file_info, file) > -1)
                        {
                                result += ({ flist[i] });
                                continue;
                        }
                }
                else
                {
                        // 如果文件本身都没有这个要找的字符串长
                        if (file_size(flist[i]) < strlen(file))
                                continue;
                       
                        if (! read_file(flist[i]))
                                continue;
                       
                        if (strsrch(read_file(flist[i]), file) > -1)
                        {
                                result += ({ flist[i] });
                                continue;
                        }
                }
        }
        return result;
}

void search_in_file(object me, string word, string file)
{
        string text, info;
        string *lines;
        int line, num, i, count = 0;
       
        seteuid(getuid(me));
        if (! text = read_file(file))
        {
                write(HIR "\n文件 " + file + " 打开失败,可能是因为文件过大。\
n" NOR);
                return;
        }
       
        if (strsrch(text, word) == -1)
        {
                write(HIR "\n文件 " + file + " 内部并无包含"" HIW + word +

                      HIR ""字符串。\n" NOR);
                return;
        }
       
        lines = explode(text, "\n");
        info = HIR "正在文件 " + file + " 中查找包含 " + word + "\n字符串的内容
:\n\n" NOR;
       
        line = sizeof(lines);
        for (i = 0; i < line; i++)
        {
                num = strsrch(lines[i], word);

                if (num > -1)
                {
                        info += WHT "在第 " + (i + 1) + " 行的第 " + (num + 1)
+ " 字节处"
                                "找到指定字符。\n" NOR;

                        info += CYN "............" NOR;
                        info += (i - 1) >= 0 ? CYN + "\n" + lines[i - 1] + "\n
" + NOR : "";
                        info += CYN + replace_string(lines[i], word, WHT + wor
d + CYN) + "\n" + NOR;
                        info += (i + 1) < line ? CYN + lines[i + 1] + "\n" + N
OR : "";
                        info += CYN "............\n\n" NOR;
                       
                        count++;
                }
        }
        info += HIR "查询完毕,一共找到 " + count + " 个符合的内容。" NOR;
       
        me->start_more(info);
        return;
}

int help(object me)
{
write(@HELP
指令格式: find <文件名|内容> in <目录名|文件名> [-c]

查找目录及其子目录下所有包含指定文件名的文件和目录。查找结果返
回的格式为:<文件名> <文件大小> <上一次修改时间>。
如果加上了 -c 参数则表示查找在指定目录下包含指定内容的文件。
如果指定的位置是一个文件名,则表示在那个文件中查找包含指定内容
的行。
HELP );
return 1;
}

给 jk 看了以后稍微改了一下,但 Eval cost 超出的问题还未能根除,
chinese_time 函数的内容:
/*
* if like chinese's time show ,can list here type to return
* type = 1 , return string like 一九九八年十月三十一日三点二十分 星期六
* type = 2 , return string like 一九九八年十月三十一日三点二十分
* type = 3 , return string like 十月三十一日三点二十分 星期六
* type = 4 , return string like 十月三十一日三点二十分
* type = 5 , return string like 1998年10月31日3点20分
* type = 6 , return string like 10月31日3点20分
* if not define type, default return string like define type =1
* if need conversion time not now() can define string get_time
* but get_time must like "Sun May  3 00:52:12 1998"
* example chinese_time(1,ctime(time())
* Make By Luky@Hero
* Last modified by jjgod@FYTX.
* Added this three:
* type = 7 , return string like 2001/03/08
* type = 8 , return string like 01/03/08
* type = 9 , return string like 2001/03/08 10:11
*/
string chinese_time(int type, string get_time)
{
        string e_time, week, month, year;
        string c_week, c_year, c_month, c_time;
        int day, hour, minute, second;
        string *month_name = ({ "Jan","Feb","Mar","Apr","May","Jun","Jul",
                                "Aug","Sep","Oct","Nov","Dec" });
        string *week_name = ({ "Mon","Tue","Wed","Thu","Fri","Sat","Sun"});

        if ( stringp(get_time) )
                e_time = get_time;
        else e_time = ctime(time());

        // e_time must is ctime(time string) like "Sun May  3 00:52:12 1998"

        sscanf(e_time,"%s %s %d %d:%d:%d %s", week, month, day, hour, minute,
second, year);

        c_week  = chinese_number(member_array(week, week_name) + 1);
        c_month = chinese_number(member_array(month, month_name) + 1);

        c_year  = sprintf("%s%s%s%s",
                chinese_number(year[0]-48),
                chinese_number(year[1]-48),
                chinese_number(year[2]-48),
                chinese_number(year[3]-48));

        c_year =c_year + "年";
        c_month  = c_month + "月";
       
        if(c_week == "七")
        c_week="日";

        c_week = " 星期" + c_week;

        c_time = chinese_number(day) + "日";
        c_time += chinese_number(hour) + "点";
        c_time += chinese_number(minute) + "分";

        if (type) {
                switch( type ) {
                        case 1: return c_year + c_month + c_time + c_week;
                        case 2: return c_year + c_month + c_time;
                        case 3: return c_month + c_time + c_week;
                        case 4: return c_month + c_time;
                        case 5: return year + "年" + (member_array(month, mont
h_name) + 1) +
                                       "月" + day + "日" + hour + "点" + minut
e + "分";
                        case 6: return (member_array(month, month_name) + 1) +

                                        "月" + day + "日" + hour + "点" + minu
te + "分";
                        case 7:
                                return replace_string(sprintf("%4s/%2d/%2d", y
ear, (member_array(month, month_name) + 1), day),
                                       " ", "0");
                        case 8:
                                return replace_string(sprintf("%2s/%2d/%2d", y
ear[2..4], (member_array(month, month_name) + 1),
                                                                             d
ay), " ", "0");
                        case 9:
                                return replace_string(sprintf("%s/%2d/%2d", ye
ar, (member_array(month, month_name) + 1), day), " ", "0")
                                       + " " + e_time[11..15];

                        default: return c_year+c_month+c_time+c_week;
                }
        }
        return c_year + c_month + c_time + c_week;
}

照顾兼容性,message_system 改成 message("system", ) 也未尝不可。


--
发信人: poet (消逝的回忆), 信区: Mud_Builder
标  题: Re: 一个搜索指令
发信站: 一塌糊涂 BBS (Wed Jul 11 20:55:18 2001)

显示文件时间没有什么必要,颜色花花绿绿更没有必要,
巫师们想不懂点Unix也难,何况许多巫师、包括mudos的创作者也是
资深Unix程序员。所以弄成Unix兼容的方式就是最好。
最好是改成grep的输出格式,既文件名、行号,该行的内容。
那样比较实用。结合ls -l就可以很方便了。
我的想法就是要让多数Unix指令都能用,或者是说让象Unix
的指令运行起来都跟Unix差不多。
要想操作灵活ls -l指令一定还是要有的。
不过最好是在mudos中内置grep功能,否则实在太消耗系统资源,
把诸如/d之类的目录搜索一遍,基本上别人就别想做任何事。

尊重作者 转载请注明出处52mud.com

收藏 推荐 打印 | 录入:sbso | 阅读:
相关内容      
内容推送
52mud提供
一起回忆泥巴游戏QQ群68186072
52mud官方微信公众平台
热门评论