日期:2014-05-16  浏览次数:20874 次

Unix下子目录的模糊跳转
原文来自:http://www2.ccw.com.cn/01/0115/c/0115c05_2.asp

在DOS或Unix操作系统下,当要进入某个子目录时,一般要输入包括绝对路径在内的全名,如果目录名较长,操作起来就会比较麻烦。这点对于经常使用Unix操作系统的人来说,体会尤为深刻。由于Unix下目录树结构错综复杂,有不少子目录,其全路径名长度可达100多个字符。而且,Unix对大小写敏感,要进入这种大小写混杂,且还可能含有其他符号的超长子目录,确实很麻烦。更麻烦的是,Unix不像DOS提供了丰富的命令行编辑功能,定义了诸多的功能键 (F1~F4、Esc、Ins、Del等),输错了可以按F3重复上一条命令并进行编辑。在Unix下一旦输错了中间的一个字符,就得全部重新输入!

那么,能不能找到一种更简洁的进入子目录的方法呢?答案是肯定的。笔者经过实践,设计了一个子目录模糊跳转的程序来代替Unix下的“cd”命令,使得Unix下子目录的跳转变得非常方便。下面介绍这一命令的实现方法。

程序功能

该命令的功能包括:首先,不用输入绝对路径;其次,不用输入目录全名。只要输入该目录名的前若干个字符即可(姑且称这种跳转方式为“普通模糊跳转方式”)。或者只输入该目录名中间的若干个字符(也就是说,不必从第一个字符开始匹配,称这种跳转方式为“高度模糊跳转方式”)。例如,我们要进入如下子目录时:

/usr/agent/ydcommunication/senddir/onl_serv

在“普通模糊跳转方式”下不管当前目录在哪里,只要在命令提示符下键入:

j onl

或用“j on”甚至“j o”均可进入该目录。当符合条件的目录有多个时,就在屏幕上列出所有符合条件的目录供选择。

如程序被设置为“高度模糊跳转方式”,只需键入:

j ser

“高度模糊跳转方式”提供了一种更为自由的跳转子目录的方式。但这种方式也有弊端,主要是同等条件下匹配的目录可能会更多。在本文介绍的方法中这个功能是可选的,可以用开关参数“-t”来进行普通模糊和高度模糊两种跳转方式的转换,用哪种跳转方式,由用户决定。

编程实现

程序文件为jj.c,部分代码如下:

#ifndef PATH_MAX

#define PATH_MAX 255

#endif

#define ENTER 0x0a

#define ESC 0x1b

#define SPACE 0x20

#define ROWS 20 /*每页显示的最大行数*/

#define MSGLINE 22

#define MAX_C 75 /*每行显示的最大字符数*/

char curdir[32],wholedir[PATH_MAX];

FILE *fp;

/*主函数*/

main(int argc,char *argv[])

{

int result=0;

initscr();refresh();

if(argc==2&&argv[1][0]==‘-’&&toupper(argv[1][1])==‘S’)

result=searchdir(0);

else if(argc==2&&argv[1][0]==‘-’'&&toupper(argv[1][1])==‘L’)

result=jumpdir(“ ”,1);

else if(argc==2&&argv[1][0]==‘-’&&toupper(argv[1][1])==‘T’)

result=turn();

else if(argc==2&&argv[1][0]!=‘-’)

result=jumpdir(argv[1],0);

else

{

mvprintw(3,10,“用法:j -s(搜索所有的目录信息)”);

mvprintw(4,10,“或者:j -l(列出所有的目录信息)”);

mvprintw(4,10,“或者:j -t(普通模糊和高度模糊跳转方式的转换)”);

mvprintw(5,10,“或者:j 目录名(跳转到指定目录)”);

mvprintw(6,10,“快速目录跳转工具 1.1 Unix 版本”);

mvprintw(8,10,“(C)版权所有 彭茂山 2000.08.21”);

mvprintw(9,10,“Email:pms@163.net ICQ:12846890 OICQ:17000112”);

mvprintw(10,10,“谢谢使用!”);

refresh();

}

echo();

endwin();

if(result) exit(-1);

exit(0);

}

/*跳转处理函数*/

jumpdir(char cdir[32],int kg)

{

FILE *fp1;

char ch,wdir[ROWS][PATH_MAX];

int i=0,j,k=0,flag=0,flag1=0;

if((fp=fopen(“/tmp/dir.inf”,“r”))==NULL)

{

mvprintw(3,10,“请先用-s参数搜索目录信息!”);

refresh();

fclose(fp);

return(-1);

}

if((fp1=fopen(“/tmp/dir1.inf”,“w”))==NULL)

{

mvprintw(3,10,“无法打开文件/tmp/dir1.inf\n”);

refresh();

fclose(fp);

fclose(fp1);

return(-1);

}

fscanf(fp,“%s”,curdir);

fflush(fp);

if(!strcmp(curdir,“!!!!!!”)) flag1=1;

else rewind(fp);

do /*开始do循环*/

{

if(k >: = ROWS) {i=0;k=0;flag=1;}

while(!feof(fp))

{

fscanf(fp,“%s%s”,curdir,wholedir);fflush(fp);

if(flag1) /*高度模糊跳转*/

{

if(kg||strstr(curdir,cdir)!=NULL)

/*列出所有符合条件的目录,如用-l参数,则kg=1,不管条件是否符合,都列出所有目录*/

{

strcpy(wdir[i],wholedir);

k+=strlen(wdir[i])/MAX_C+1;

i++;

}

}

else /*普通模糊跳转*/

{

if(kg||!strncmp(curdir,cdir,strlen(cdir))){

strcpy(wdir[i],wholedir);

k+=strlen(wdir[i])/MAX_C+1;

i++;