益友软件工作室 - 为您打造功能强大的加密软件产品
加密金刚锁是一款集加密、文件加密、文件夹加密、文件夹隐藏等加密软件技术于一体的安全软件

加密金刚锁相关技术 → C语言类技术文章 → Unix下子目录的模糊跳转

Unix下子目录的模糊跳转

文章作者:彭茂山 黄贵清 林直友
 

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

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

程序功能

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

/usr/agent/ydcommunication/senddir/onl_serv

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

j onl

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

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

j ser

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

编程实现

程序文件为jj.c

其他处理

该程序可用如下命令编译(SCO OpenServer 5.05下编译通过)

cc o jj jj.c lcurses lc

基于Unix下子进程的修改对父进程无效的特性,让上述程序在主程序中直接实现子目录的跳转尚有困难。为此,笔者先在主程序中只生成目标目录的全路径名,存于文件/tmp/dir1.inf中,然后再编一个shell程序ju做进一步处理。

j()

{

  > /tmp/dir1.inf

  /etc/jj $1

  dir='cat /tmp/dir1.inf|awk '{print $1}''

  if ["$dir" = "" ]then

  return

  else

  cd $dir

  echo $dir

  echo Success!

  fi

}

shell程序的作用是定义一个私有函数j(),该函数将根据/tmp/dir1.inf的内容实现对子目录的跳转。将jjju两个文件拷入/etc目录下,用如下命令将两个文件的权限改为最大:

chmod 777 /etc/jj /etc/ju

这样就使任何用户都有使用权限。

最后,修改各用户的.profile文件,在该文件最后追加一句:

./etc/ju (注意:“.”和“/etc/ju”之间有个空格)

这样处理后,就可以用“j(注意:是“j”而不是“ju)命令来代替“cd”命令了。最后还要注意的是,第一次使用时,要用“-s”参数扫描目录信息,并把扫描结果存于文件/tmp/dir.inf中。如果以后目录结构发生改变,也要重新扫描目录信息

                            

/*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@tom.com  ICQ:12846890  OICQ:17000112");

    mvprintw(10,10,"欢迎光临我的网站:http://www.encrypter.net");

    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_C1;

          i++;

        }

      }

      else  /*普通模糊跳转*/

      {

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

        strcpy(wdir[i],wholedir);

          k=strlen(wdir[i])/MAX_C1;

          i++;

        }

      }

      /*控制每屏显示的行数*/

      if(k   >=  ROWS) break; 

    }/*结束while(!feof(fp))*/

    /*只有一条目录符合条件*/

    if(i==1&&!flag) 

    {

      /*将要跳转的目录名写到/tmp/dir1.inf*/

      fprintf(fp1,"%s",wdir[0]);

      fclose(fp);

      fclose(fp1);

      return(0);

   }

   else if(i!=0)

   {

      clear();

      k=0;

      for(j=0;j<i;j++)

      {

          system("setcolor red");

          mvprintw(k,0,"[%c]",j'A');

          refresh();

          system("setcolor white");

          mvprintw(k,3,"->%s",wdir[j]);

          refresh();

          k=strlen(wdir[j])/MAX_C1;

      }

      system("setcolor red");

      mvprintw(k1,0,"<Enter>");

      refresh();

      if(!feof(fp)) {

          system("setcolor white");

          mvprintw(k1,7,"下一页,");

          refresh();

      }

      else {

          system("setcolor white");

          mvprintw(k1,7,"中断,");

          refresh();

      }

      system("setcolor red");

      mvprintw(k1,14,"<ESC>");refresh();

      system("setcolor white");

      mvprintw(k1,19,"中断,");refresh();

      system("setcolor red");

      mvprintw(k1,24,"<Space>");refresh();

      system("setcolor white");

      mvprintw(k1,31,"-");refresh();

      system("setcolor red");

      mvprintw(k1,33,"[A]");refresh();

      system("setcolor white");

      mvprintw(k1,36,",");refresh();

      system("setcolor red");

      mvprintw(k1,37,"<A>");refresh();

      system("setcolor white");

      mvprintw(k1,40,"->");refresh();

      system("setcolor red");

      mvprintw(k1,42,"<  %c >",'A'i-1);refresh();

      system("setcolor white");

      mvprintw(k1,46,"跳转到相应目录,请选择:");refresh();

      ch=getch();

      /*选择错,请重新输入*/

      while((toupper(ch)<'A'||toupper(ch)>='A'

i)&&ch!=ESC&&ch!=ENTER&&(!isspace(ch)))

      {

          beep();

          mvprintw(MSGLINE,0,"选项输入错,正确选项是:A->%c\n",'A'i-1);

          refresh();

          move(k1,70);

          ch=getch();

       }

    }/*结束 else if(i!=0) */

  }while(ch==ENTER&&!feof(fp));

  clear_in(MSGLINE);

  if(ch==ESC||ch==ENTER&&feof(fp)){

    mvprintw(MSGLINE,0,"用户中断, 谢谢使用!");

    refresh();

    fclose(fp);

    fclose(fp1);

    return(0);

  }

  if(isalpha(ch)) ch=toupper(ch);

  if(isspace(ch)) ch='A';

  if(i>0)

    fprintf(fp1,"%s",wdir[ch-'A']);

  else {

    mvprintw(22,0,"目录未找到!\n");

    refresh();

    return(-1);

  }

  fclose(fp);

  fclose(fp1);

  return(0);

}/*结束jumpdir()函数*/

/*查找匹配目录*/

searchdir()

{

  if((fp=fopen("/tmp/dir.inf","w"))==NULL){

     mvprintw(MSGLINE,0,"文件dir.inf打不开");

     refresh();

     return(-1);

  }

  clear_in(MSGLINE);

  mvprintw(MSGLINE,0,"正在搜索目录信息,时间可能比较长,请耐心等候...\n");

  refresh();

  /*调用搜索子目录的递归子函数*/

  shdir("/"); 

  clear_in(MSGLINE);

  mvprintw(MSGLINE,0,"目录搜索完毕!");

  refresh();

  fclose(fp);

  return(0);

}

/*搜索子目录的递归子函数*/

shdir(char *sdir)

{

  DIR *dirp;

  char wholedir[PATH_MAX];

  struct dirent *dirment;

  struct stat statbuf;

  char olddir[PATH_MAX];

  getcwd(olddir,PATH_MAX);

  if((dirp=opendir(sdir))==NULL) return(-1);

  chdir(sdir);

  while((dirment=readdir(dirp))!=NULL)

  {

    stat(dirment->d_name,&statbuf);

    /*是子目录(不包括...子目录)*/

    if((statbuf.st_mode&S_IFDIR)&&(statbuf.st_mode<20000)&&strcmp(dirment->d_name,".")&&strcmp(dirment->d_name,".."))

    {

      getcwd(wholedir,PATH_MAX);

      if(wholedir[strlen(wholedir)-1]=='/')

        {strcat(wholedir,dirment->d_name);}

      else {

         strcat(wholedir,"/");

         strcat(wholedir,dirment->d_name);

      }

      /*将所有的目录信息写到/tmp/dir.inf*/

      fprintf(fp,"%-34s%2s%s\n",dirment->d_name," ",wholedir);

      /*调用递归子函数*/      

      fflush(fp);

      shdir(dirment->d_name);

    }

  }/*结束while*/

  chdir(olddir);

  closedir(dirp);

  return(0);

}

clear_in(int i)

{move(i,0);clrtoeol();}

/*查找模式转换处理*/

turn()

{

  FILE *fp1;

  char buf[290];

  if((fp=fopen("/tmp/dir.inf","r"))==NULL){

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

    refresh();

    fclose(fp);

    return(-1);

  }

  if((fp1=fopen("/tmp/tmpf","w"))==NULL)

  {

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

    refresh();

    fclose(fp);

    fclose(fp1);

    return(-1);

  }

  fgets(buf,290,fp);

  if(strncmp(buf,"!!!!!!",6))   

  {

    rewind(fp);

    fputs("!!!!!!\n",fp1);

  }

  while(!feof(fp)) fputc(fgetc(fp),fp1);

  fclose(fp);

  fclose(fp1);

  system("mv /tmp/tmpf /tmp/dir.inf");

  if(strncmp(buf,"!!!!!!",6)){

    mvprintw(3,10,"OK,现在已转成高度模糊跳转方式.");

    refresh();

  }

  else {

    mvprintw(3,10,"OK,现在已转成普通模糊跳转方式.");

  refresh();

  }

   return(0);

}

 

特别申明

本栏目的文章都是本人从网上搜集而来,仅供大家学习研究之用,请不要用于商业目的!其中署名“佚名”的,意思是作者不详。如果某些文章未署你的名字,请来信告知,我会补上的。如果你认为某些文章侵犯了你的正当权宜,也请来信,我会将它删除。