2011-12-03 | #1 |
高级会员
注册: 08年04月11日
来自: 盘丝洞
帖子: 311
声望力: 20
声望:
50
现金:29两梁山币
资产:1245两梁山币
致谢数: 0
获感谢文章数:0
获会员感谢数:0 |
一个搜索指令
发信人: jjgod (jjgod), 信区: Mud_Builder 标 题: 一个搜索指令 发信站: 一塌糊涂 BBS (Wed Jul 11 13:14:08 2001) // 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之类的目录搜索一遍,基本上别人就别想做任何事。 |
|