当前位置:Linux教程 - Linux - Linux下文件操作编程和GAWK的介绍和应用

Linux下文件操作编程和GAWK的介绍和应用

最近学着用Linux上网,结果经常忘了网址,就mount上c盘,打开windows/favorites/用notepad打开???.url,再Ctrl+c和Ctrl+v,才浏览上该网址,但很不方便。于是就想把书签都从*.url中提取出来,可是用”Ctrl cv”大法不是办法,太麻烦了,现在什么事情都要“自动化”,因此就着手编个程序来实现。

  大概原理:

  从起始目录搜索各个子目录,用GAWK从各个url文件中把网址提取出来,用重定向符“>”存成文件。

  首先,来介绍一下GAWK。GAWK是一个资料处理的程序,能用相当简短的语句来完成字符串处理功能。现在以”CPCW网站.url”文件为例,介绍一下。

  CPCW网站.url有以下内容

  [DEFAULT]

  BASEURL=http://www.cpcw.com/

  [InternetShortcut]

  URL=http://www.cpcw.com/

  Modified=2098A2DAC868BF0124

  在shell中输入gawk /url/ {print $0} CPCW网站.url

  输出如下:

  BASEURL=http://www.cpcw.com/

  URL=http://www.cpcw.com/

  Gawk格式为: gawk ‘表达式 {动作} 表达式 {动作}…..’ 要处理的文件1 文件2…..

  Gawk 读入文件首先以内部变量RS为分界符,把文件内容分成一个一个记录,再以FS把记录分解成栏位。一个记录的第一个栏位为$1,第二个为$2…..$0为该记录。Gawk一个一个记录地处理,如果符合任意一个表达式,就会执行该表达式后面的动作。

  常见表达式有以下几个:

  xxxxx/ {print $0} 只要记录有字符串xxxxx,就输出该记录。

  $1= =match {print $2} 如果记录的第一个栏位是match,就输出第二个栏位。除了==,还有&&,||,!学过C的一定不会陌生!

  回到正题,怎样提取http://www.cpcw.com/ 呢?只要把栏位分界符FS设为”=”,如果$1==”URL”,那$2就是网址了。整条命令为:

  gawk ''BEGIN {FS=""=""} $1==""URL"" {print $2}''

  BEGIN 后面的动作唯一开始就强行执行的,类似的还有END

  接着就是文件操作,这里主要是打开目录,获得目录中的文件名,用到函数有:

  #include

  DIR *opendir(char *pathname); //打开成功返回一目录指针

  struct dirent *readdir(DIR *dirptr); //返回指向结构dirent的指针dirent->d_name为一字符

    //数组,存放着该目录中的文件名,调用一次readdir(),

    //d_name就存放下一个文件名,当返回0时,表明已经读完了。

  int closedir(DIR *dirptr); //工作完成后,别忘了关闭连接

  其次,就要判断一个文件名是文件还是目录:

  #include

  int stat(char *pathname,struct stat *sbuf); //调用之后,sbuf.st_mode存放文件类型值

    // if (sbuf.st_mode&S_IFMT==S_IFDIR) 是目录

    // else 不是目录

  本程序采用递归的方式,找到一个目录,就进入搜索,否则就调用system()执行shell命令

  使用方法:

  比如,书签放在/c/windows/Favorites/下,输出文件为/home/url

  就执行 程序名 /c/windows/Favorites/ /home/url

  使用的时候才发现,由于gawk的限制,文件名中不能有空格,+,&等符号,也是要我修改,不过收获也挺多!如果有疑问,就email给我一起交流  ([email protected]

  附:源程序

  #include

  #include

  #include

  #include

  #include

  char command[60];

  char rootdir[50]; //起始目录

  char pwd[500]; //pwd为当前目录

  char output[20];

  main(int argc,char *arg[])

  {

    DIR *d;

    strcpy(rootdir,arg[1]);

    strcpy(pwd,rootdir);

    strcpy(command,""gawk ''BEGIN {FS=""=""} $1==""URL"" {print $2}''"");

    strcpy(output,arg[2]);

    if (d=opendir(rootdir))

      chuli(d);

  }

  chuli(DIR *d)

  {

    struct dirent *link;

    char temp[300];

    char bakpwd[300];

    strcpy(bakpwd,pwd); //保存当前目录,供递归后恢复pwd

    link=readdir(d); /*skip . */

    link=readdir(d); /*skip .. */

    while((link=readdir(d))!=0)

    {

    if (isdir(link->d_name)==S_IFDIR)

    { //是目录,改变当前目录,进入该目录,递归

    sprintf(pwd,""%s%s/"",bakpwd,link->d_name);

    chuli(opendir(pwd));

    }

    else

    { // “>>”为重定向符,向指定文件追加内容

    sprintf(temp,""%s %s%s>>%s"",command,pwd,link->d_name,output);

    system(temp);

    }

    strcpy(pwd,bakpwd); //恢复pwd

    }

    closedir(d);

    return;

  }

  isdir(char *name)

  {

    struct stat sbuf;

    char temp[200];

    sprintf(temp,""%s%s"",pwd,name);

    stat(temp,&sbuf);

    return (sbuf.st_mode)&S_IFMT;

  }