zoukankan      html  css  js  c++  java
  • 打磨程序员的专属利器——文本

    打磨程序员的专属利器分三个专题展示--

    1. 命令行&文件

    2. 快捷键

    3. 文本 (本文)

    1. 记笔记

    好记性不如烂笔头,对于程序员更是如此。学习某种新语言或者某个库,若事先不记点笔记,几年后再拣起来会非常地慢。

    之前自己一直用“为知笔记”,但慢慢发现了几个问题。

    a. 这个软件喜欢升级,而每次升级都将界面改得面目全非(其实现在绝大多数软件都喜欢没事升级)。我只是想一个简洁的软件界面,只想专注于笔记,而为知的每一次更新后都得花精力在熟悉界面上。

    b. 为知的笔记不是文本,这样笔记内容几乎只能用为知才能打开。如果想在ubuntu或者Mac上看,只有期待它出对应的客户端或者用网页查看(但如果没网时也不能查看本地数据了)。不过现在我打开wiz的网页版笔记,只能另我大失所望,本人只是想要一个左边是树形控件展示笔记的结构,右边可以显示笔记内容的界面,而wiz网站的在线笔记做得太复杂了。

    c. 有时不知是服务器还是网络问题,同步居然出现问题。在家里电脑写的东西,来到公司后发现居然没有同步过来,fuck!!!!

    忍无可忍后,就动了自己实现个笔记软件的想法。最开始是用c#写,笔记保存成.mht格式,用IE控件进行预览,用word进行编辑(这是从wiz中得到的启发)。不过后来也发现不是文本的笔记根本不能跨平台。于是又重写了一遍,用c++实现,下面是软件的界面,很简洁,但完全够自己用了。

    这个程序从底层反锯齿的2d图形库,到界面库,到Markdown的解析,都是自己重新造轮子实现(虽说在软件界不鼓励重新造轮子,但通过造轮子可以将图形库、界面库理解得更透彻)。由于太过简陋就不发布出来,等过段时间有空了用QT再重写一个相对漂亮点的界面再公布源码和程序。

    2. Markdown

    上面的笔记中提到了Markdown。《程序员修炼之道》中提到笔记得到文本来记录。最开始本人一直认为“文本”就是“纯文本”,直到在开源软件中发现有.md文件,于是知道了有Markdown这种东东,然后忽然识别到文本也可以做得很漂亮(html,css就是文本)。

    Markdown是html的一个子集。可以用少量的标示符就可以构造出漂亮的文本排版。下面简单介绍下Markdown的标示符:

    a. 行首的#可以指明段落,一个表示第一级,二个表示第二级,以此类推

    b. 两行```之间的内容可以被解析为code格式,就像上图中有灰色背景的区域,这种可以方便放代码。

    c. 行首的 * 可以被解析成html的 <li>

    d. 用[name](http://www.test.com "test") 这种格式可以指定超链接

    e. 用下面的格式可以构造出如下的表格

    name | age
    ---|---
    man1 | 45
    man2 |2

    .... 

    更多Markdown语法可以参数其官网。反正都挺好学,也比较易用,可以在记笔记时不因格式问题而花太多的精力,让我们专注于内容

    3. 备份、同步

    有了上面DIY的笔记软件后,对于多地办公、多台电脑办公就得考虑如何同步笔记了。

    开始本人是使用金山网盘,但也是因为同步问题,有时真是金山的服务器挂了,导致无法同步。还一个严重的问题,网盘没有像svn,git那样明确的update,commit,pull,push操作,这样在同步时真就会出现问题。然后本人试了几乎所有的网盘,发现在某些情况下100%的情况会出现同步失败的问题。

    ************************

    在写这篇博文时为了再次证实下,于是本人又装了次金山快盘。

    新建一个文件夹,在这个文件夹下再新建两个文本文档,往其中一个文本文档中随便写点东西,这时去网页版的金山快盘上,就发现真就没有把刚才的东西同步上来。比吃了蟑螂还恶心!!!

    qq云盘和360网盘以前还可以在Explorer中查看本地数据,但现在只有用它自己的程序来操作本地数据了。

    百度云盘同样也有这样问题,没有本地路径。

    ************************

    同样是忍无可忍

    开始使用 http://svn.jundie.net/,但由于本人小气,不想花钱买私有项目,只有把自己的笔记弄成开源项目,虽说没什么重要东西,但总感觉不靠谱。

    于是找到git.oschina.net,并且发现基于git有非常多的服务器,并且都可以免费申请私有项目。于是爱上了git,为了保险,将自己所有的代码都放到git上,当然是私有项目(遥想当年,由于本人折腾电脑、折腾分盘,将大一下刚学程序半年写的vb6俄罗斯方块程序源码弄丢了,多么地心疼啊)~~

    于是妈妈再也不用担心代码弄丢了

    为了方便在Explorer中访问笔记,可以使用前文介绍的subst命令,将笔记路径映射成一个虚拟磁盘以便访问。 

    4. 学习一门文本语言

    《程序员修炼之道》中说程序员应该每一年学习一门新语言,我们打个折扣1~2年学习一门新语言。并且非常有必要学习一门文本操作语言,比如Python,Ruby或者是Perl。虽然用C#,java,甚至是c/c++都可以进行文本操作,但编写代码的速度肯定不及脚本语言。

    本人最开始学习的是Perl语言。这门语言咋一看觉得不好学——充满了各种奇奇怪怪的符号。不过如果沉下心来将《Perl语言入门》、《Perl语言编程》两本书看完,然后再动手自己写几个实用的小程序,Perl的学习之路基本上就算是毕业了。

    下面展示几个本人所写的perl程序。也是比较简陋(本人侧重于实用):

    a. ls程序

    linux下的ls命令可以将当前路径下的文件、文件夹都显示出来。windows下没有这样的程序,于是本人实现了一个。

      1 use 5.010;
      2 use strict;
      3 use warnings;
      4 
      5 use Win32::Console;
      6 use Win32::Console::ANSI;
      7 use Term::ANSIColor;
      8 use POSIX();
      9 
     10 
     11 use utf8;
     12 use Encode::Locale;
     13 
     14 binmode STDIN, ":encoding(console_in)";
     15 binmode STDOUT, ":encoding(console_out)";
     16 binmode STDERR, ":encoding(console_out)";
     17 
     18 sub Main;
     19 
     20 Main @ARGV;
     21 
     22 my $is_dir_show;
     23 my $is_file_show;
     24 
     25 my $is_show_size;
     26 my $is_sort_by_size;
     27 
     28 my @folds;
     29 my @files;
     30 
     31 my $max;
     32 
     33 my $col_count;
     34 my $col_width;
     35 
     36 my $con_w;
     37 my $con_h;
     38 
     39 sub Help {
     40     #system("chcp 936");
     41     my $str = "ls 显示当前目录下的文件和文件夹名
    ".
     42     "默认情况下文件和文件夹都将显示。-f 显示文件   -d 显示文件夹
    ".
     43     "默认情况下不显示文件和文件夹的大小。   -s 将显示其大小
    ".
     44     "如果文件名中有中文,则一定要确保控制台的代码页为936,用chcp 936可以改变代码页";
     45     print $str;
     46 }
     47 
     48 sub IsHelp {
     49     foreach (@_) {
     50         if (lc($_) eq '?' ||
     51         lc($_) eq '/?' ||
     52         lc($_) eq '-help' ||
     53         lc($_) eq '--help'
     54         ) {
     55             return 1;
     56         }
     57     }
     58     return 0;
     59 }
     60 
     61 #---------------
     62 # 判断命令行中是否有-d,如果有则表示显示文件夹
     63 #---------------
     64 sub IsDir {
     65     foreach (@_) {
     66         if (lc($_) eq '-d') {
     67             return 1;
     68         }
     69     }
     70     return 0;
     71 }
     72 #---------------
     73 # 多年命令行中是否有-f,如果有则表示显示文件
     74 #---------------
     75 sub IsFild {
     76     foreach (@_) {
     77         if (lc($_) eq '-f'){
     78             return 1;
     79         }
     80     }
     81     return 0;
     82 }
     83 #---------------
     84 # 判断命令行中是否有-s, 如果有则要显示大小
     85 #---------------
     86 sub IsSize {
     87     foreach (@_) {
     88         if (lc($_) eq '-s') {
     89             return 1;
     90         }
     91     }
     92     return 0;
     93 }
     94 
     95 #---------------
     96 # 判断命令行是否有-S,如果有则要按照文件大小排序,并且显示文件大小
     97 #     即-S包含-s
     98 #---------------
     99 sub IsSortBySize {
    100     foreach (@_) {
    101         if ($_ eq '-S') {
    102             return 1;
    103         }
    104     }
    105     return 0;
    106 }
    107 #---------------
    108 # 获取文件夹的大小
    109 # par_1: path
    110 #---------------
    111 sub GetFoldSize {
    112     my $path = shift;
    113     my $size = 0;
    114 
    115     if (-d $path) {
    116         my $r = opendir(DIR, $path);
    117 
    118         if (!$r) {
    119             return 0;
    120         }
    121 
    122         my @files = readdir(DIR);
    123         closedir(DIR);
    124 
    125         foreach (@files) {
    126             next if $_ eq '.' or $_ eq '..';
    127             my $file = "$path\$_";
    128 
    129             if (-d $file) {
    130                 $size += GetFoldSize($file);
    131             } else {
    132                 my $s = (-s $file);
    133                 $size = $size + $s;
    134 
    135             }
    136         }
    137     }
    138     return $size;
    139 }
    140 
    141 #---------------
    142 # 将字节数转化为G M K 显示
    143 # par_1:byte_size;
    144 #---------------
    145 sub ByteToString {
    146     my $b = shift;
    147     my $k=0;
    148     my $m=0;
    149     my $g=0;
    150 
    151     if ($b >= 1024) {
    152         $k = int($b/1024);
    153         $b -= $k * 1024;
    154     }
    155 
    156     if ($k >= 1024) {
    157         $m = int($k/1024);
    158         $k -= $m * 1024;
    159     }
    160 
    161     if ($m >= 1024) {
    162         $g = int($m/1024);
    163         $m -= $g * 1024;
    164     }
    165 
    166 #    my $str="";
    167 #    my $temp;
    168 #    if ($g != 0) {
    169 #        $str .= "$g"."G";
    170 ##        $str .= $temp." "x(6 - length($temp)) ;
    171 #    }
    172 #    if ($m != 0) {
    173 #        $str .= "$m"."M ";
    174 ##        $str .= $temp." "x(6 - length($temp)) ;
    175 #    }
    176 #    if ($k != 0) {
    177 #        $str .= "$k"."K ";
    178 ##        $str .= $temp." "x(6 - length($temp)) ;
    179 #    }
    180 #    if ($b != 0) {
    181 #        $str .= "$b"."B ";
    182 ##        $str .= $temp." "x(6 - length($temp)) ;
    183 #    }
    184     
    185     if ($g) {
    186         sprintf("%4dG %4dM %4dK %4dB", $g, $m, $k, $b);
    187     } elsif ($m) {
    188         sprintf("%10dM %4dK %4dB", $m, $k, $b);
    189     } elsif ($k) {
    190         sprintf("%16dK %4dB", $k, $b);
    191     } else {
    192         sprintf("%22dB", $b);
    193     }
    194     
    195 
    196 #    if ($str eq "") {
    197 #        return "0B";
    198 #    }
    199 #
    200 #    return $str;
    201 }
    202 
    203 #---------------
    204 # 获取数组中最大的字符串长度
    205 # par:@_ 数组
    206 #---------------
    207 sub MaxLength {
    208     my $max = 0;
    209 
    210     foreach (@_) {
    211         my $len = length $_;
    212         if ($len > $max) {
    213             $max = $len;
    214         }
    215     }
    216     return $max;
    217 }
    218 
    219 #---------------
    220 # 根据获取的col_count, col_width打印文件和文件夹名
    221 # 在没有-s选项中这样显示,只显示文件夹名和文件名
    222 # par:@_ 文件或文件夹名数组
    223 #---------------
    224 sub PrintFileName {
    225     my $c = 0;
    226 
    227     foreach (@_) {
    228         my $s = $_;
    229         print Encode::decode("gb2312", $s);
    230 
    231         my $len = length $_;
    232         my $diff = $col_width - $len -1; #-1 是为了防止窗口宽等于缓冲区宽时引起的空白行问题
    233         my $black = " " x $diff;
    234         print $black;
    235 
    236         ++$c;
    237         if ($c == $col_count) {
    238             print "
    ";
    239             $c = 0;
    240         }
    241     }
    242 }
    243 
    244 #---------------
    245 # 当不指定显示大小,或者不按大小排序时显示文件
    246 #---------------
    247 sub PrintNoSize {
    248     my $console = Win32::Console->new();
    249     ($con_w, $con_h) = $console->Size();
    250 
    251     $col_count = POSIX::floor($con_w / ($max+4));
    252     if ($col_count == 0) {
    253         $col_count = 1;
    254     }
    255     $col_width = POSIX::floor($con_w / $col_count);
    256 
    257     #print "screen_ $con_w 
    ";
    258     #print "max_ $max 
    ";
    259     #print "col_cout: $col_count
    ";
    260     #print "col_ $col_width 
    ";
    261 
    262     if ($is_dir_show && scalar(@folds)) {
    263         my $c = $#folds+1;
    264         my $s = "文件夹: $c 个
    ";
    265         print $s;
    266         print color 'bold yellow';
    267         PrintFileName @folds;
    268         print color 'reset';
    269         print "
    ";
    270     }
    271 
    272     if ($is_file_show && scalar(@files)) {
    273         my $c = $#files+1;
    274         my $s = "文件: $c 个
    ";
    275         print $s;
    276         print color 'bold green';
    277         PrintFileName @files;
    278         print color 'reset';
    279     }
    280 }
    281 
    282 #---------------
    283 # 显示文件或文件夹的大小
    284 #---------------
    285 sub PrintBySize {
    286     
    287     my $width = $max + 4;
    288     
    289     if ($is_dir_show) {
    290         
    291         my %hash_dir;
    292         foreach (@folds) {
    293             $hash_dir{$_} = GetFoldSize($_);
    294         }
    295         
    296         my @k;
    297         if ($is_sort_by_size) {
    298             @k = sort { $hash_dir{$b} <=> $hash_dir{$a} } keys %hash_dir;
    299         } else {
    300             @k = sort keys %hash_dir;
    301         }
    302 
    303         foreach (@k) {
    304             print color 'bold yellow';
    305             print $_;
    306             print color 'reset';
    307 
    308             my $len = length $_;
    309             my $diff = $width - $len;
    310             my $black = " " x $diff;
    311             print $black;
    312 
    313             print ByteToString($hash_dir{$_});
    314             print "
    ";
    315         }
    316     }
    317     if ($is_file_show) {
    318         my %hash_file;
    319         
    320         foreach (@files) {
    321             $hash_file{$_} = -s $_;
    322         }
    323         
    324         my @k;
    325         if($is_sort_by_size) {
    326             @k = sort { $hash_file{$b} <=> $hash_file{$a}} keys %hash_file;
    327         } else {
    328             @k = sort keys %hash_file;
    329         }
    330         
    331         foreach (@k) {
    332             print color 'bold green';
    333             print $_;
    334             print color 'reset';
    335 
    336             my $len = length $_;
    337             my $diff = $width - $len;
    338             my $black = " " x $diff;
    339             print $black;
    340             print ByteToString($hash_file{$_});
    341             print "
    ";
    342         }
    343     }
    344 }
    345 
    346 sub List {
    347     $is_dir_show = IsDir @_;
    348     $is_file_show = IsFild @_;
    349     $is_show_size = IsSize @_;
    350     $is_sort_by_size = IsSortBySize @_;
    351 
    352     #如果即没有指定-f,也没有指定-d,则默认为都显示
    353     if (!$is_dir_show && !$is_file_show) {
    354         $is_dir_show = 1;
    355         $is_file_show = 1;
    356     }
    357 
    358     opendir(DIR, '.');
    359     my @file = readdir(DIR);
    360     closedir(DIR);
    361 
    362     foreach (@file) {
    363         next if $_ eq '.' or $_ eq '..';
    364 
    365         if (-d $_) {
    366             push(@folds, $_);
    367 
    368         } else {
    369             push(@files, $_);
    370         }
    371     }
    372 
    373     my $len1 = MaxLength @folds;
    374     my $len2 = MaxLength @files;
    375     $max = $len1 > $len2 ? $len1 : $len2;
    376 
    377     if ($is_show_size) {
    378         PrintBySize;
    379 
    380     } else {
    381         PrintNoSize;
    382     }
    383 
    384 }
    385 
    386 sub Test {
    387     #$s = "d:\1.jpg";
    388     #my $size = GetFoldSize "d:\lib";
    389     #print ByteToString $size;
    390 
    391     #print length($str);
    392 
    393 #    opendir(DIR, "e:\");
    394 #    my @files = readdir(DIR);
    395 #    closedir(DIR);
    396 
    397 #    foreach (@files) {
    398 #        print $_, "
    ";
    399 #    }
    400 
    401     my $len = -s "D:\pagefile.sys";
    402     print "$len 
    ";
    403     print ByteToString($len) , "
    ";
    404 }
    405 
    406 sub Main {
    407     if (IsHelp @_) {
    408         Help;
    409     } else {
    410         List @_;
    411 #        Test;
    412     }
    413 }
    View Code

    将上面的代码保存为ls.pl,放在系统路径中。然后在命令行中就可以用 perl ls.pl 来执行它。如果嫌这个命令太复杂,就想用ls来执行它,可以这样,在系统路径中建立一个ls.bat文件,内容为

    @echo off
    perl e:Toolsls.pl %*

    这样输入ls时,先执行ls.bat文件,然后在这个文件中再真正执行perl代码(这里指定ls.pl的路径得用绝对路径)。其中%*是将 ls后面所有的命令行选项传递给ls.pl。

    ls所支持的命令行选项有:

    • ls  -f 只显示文件
    • ls -d 只显示文件夹
    • ls -s 显示文件或文件夹的大小
    • ls -S 按文件大小排序后再显示

    b. grep程序

    当我们阅读某个开源项目时往往想找一个类名、或者一个变量名在哪些地方使用过,如果这时没有将项目组织用IDE组织起来,想要查找就比较麻烦。在linux下有个grep可以对文本进行搜索,然后本人就用perl写了一个类似grep的程序,可以在文本文件中查找字符串,并且可以指定在特定的文件上查找。

      1 use 5.010;
      2 use strict;
      3 use warnings;
      4 use Cwd;
      5 
      6 use Win32::Console::ANSI;
      7 use Term::ANSIColor;
      8 
      9 sub Main;
     10 sub MainTest;
     11 
     12 Main @ARGV;
     13 #MainTest;
     14 
     15 #--------------
     16 # return 返回是否只查看一级目录,bool
     17 #--------------
     18 sub OnlyLocal {
     19     foreach (@_) {
     20         if (lc($_) eq '-l') {
     21             return 1;
     22         }
     23     }
     24     return 0;
     25 }
     26 
     27 #--------------
     28 # 获取命令行参数的一般方法
     29 # 用法 :GetPar('-f', @_);
     30 # return 返回第一个参数后面的字符串
     31 #--------------
     32 sub GetPar {
     33 
     34     my $next = 0;
     35     my $str = $_[0];
     36     shift @_;
     37     #say @_;
     38     foreach (@_) {
     39         if ($next) {
     40             return $_;    
     41         }
     42         if ($_ =~ /Q$str/i) {
     43             $next = 1;
     44         }
     45     }
     46     return '';
     47 }
     48 
     49 #--------------------
     50 # param 输入的命令行
     51 # return 返回 -f后面的值
     52 #--------------------
     53 sub FileExp {
     54 
     55     my $s = &GetPar('-f', @_);
     56     if ($s ne '') {
     57         return $s;    
     58     }    
     59     return '';
     60 }
     61 
     62 #--------------------
     63 # return 返回 -t 后面的值
     64 #--------------------
     65 sub TxtExp {
     66     return &GetPar('-t' ,@_);
     67 }
     68 
     69 my $is_loc;
     70 my $file_exp;
     71 my $txt_exp;
     72 my $count;
     73 my @scan_files;
     74 
     75 #--------------
     76 # 用 $txt_exp查找文件中的每一行,返回所有符合条件的行
     77 #--------------
     78 sub ScanFile {
     79     my $file = shift;
     80     my @text;
     81     
     82     open(FILE, "$file");
     83     while (<FILE>) {
     84         if (/$txt_exp/i) {
     85             #return 1;
     86             push(@text, $_);
     87         }
     88     }
     89     close FILE;
     90     #return 0;
     91     return @text;
     92 }
     93 
     94 sub PrintColor;
     95 #--------------
     96 # 用不同颜色来突出显示匹配到的文本
     97 # par_0@:line_text
     98 #--------------
     99 sub PrintColor {
    100     my $text = shift;
    101     
    102     if ($text =~ /$txt_exp/i) {
    103     
    104         print $`;
    105         
    106         print color 'bold red';
    107         print $&;
    108         print color 'reset';
    109         
    110         
    111         PrintColor $';   #'为了消除$后面的影响
    112         
    113     } else {
    114         print $text;
    115     }
    116 
    117 }
    118 
    119 #--------------
    120 # 显示文件信息
    121 # par_0: $file
    122 # par_1: @text
    123 #--------------
    124 sub PrintFile {
    125     my $file = shift;
    126     
    127     print color 'bold cyan'; 
    128 
    129     print "$count  $file
    ";
    130     print color 'reset';
    131         
    132     ++$count;
    133     push(@scan_files, $file);
    134     
    135     #现在一个文件中只显示一条信息
    136     
    137     $_[0] =~ s/^s+|s+$//g; #去掉前后的空格
    138     $_[0] =~ s/s+/ /g; #将多个空格替换成一个空格
    139 
    140     print "    ";
    141     PrintColor $_[0];
    142     print color 'reset';
    143     print "
    
    ";
    144     
    145 }
    146 
    147 #--------------
    148 # 查看一级目录中的文件
    149 # param: $dir
    150 #--------------
    151 sub ScanFold {
    152     
    153     my $dir = shift;
    154     opendir(DIR, "$dir");
    155     my @files = readdir(DIR);
    156     closedir(DIR);
    157     
    158     foreach (@files) {
    159         next if $_ eq '.' or $_ eq '..';
    160         my $file = "$dir\$_";
    161         
    162         if (-d $file) {
    163             if (!$is_loc) {
    164                 ScanFold($file);
    165             }
    166             
    167         } else {
    168             
    169             my $file_valid = 0;
    170             
    171             #如果文件表达式为空,则判断文件是否为文本文件
    172             #否则用文件表达式去匹配 $_
    173             if ($file_exp eq '') {
    174                 $file_valid = -T $file;
    175             } else {
    176                 $file_valid = /$file_exp/i;
    177             }
    178         
    179              if ($file_valid) {
    180                 
    181                 if ($txt_exp ne '') {
    182                     my @text = &ScanFile($file);
    183                     
    184                     if ($#text >= 0 ) {  # $#text是最后一个数组元素的index
    185                         PrintFile($file, @text);
    186                     }
    187                     
    188                 } else {
    189                     print color 'bold cyan';
    190                     print "$count $file
    ";
    191                     print color 'reset';
    192                                         
    193                     ++$count;
    194                     push(@scan_files, $file);
    195                 }
    196              }
    197         }
    198         
    199     }
    200 }
    201 
    202 sub isnumeric {
    203     my $val = shift;
    204     ($val ^ $val) eq '0';    
    205 }
    206 
    207 sub Scan {
    208 
    209     $is_loc = &OnlyLocal(@_);
    210     
    211     $file_exp = &FileExp(@_);
    212     $txt_exp = &TxtExp(@_);
    213     
    214     $count = 0;
    215     
    216     if ($file_exp eq '' && $txt_exp eq '' && $#_==0) {
    217         $txt_exp = $_[0];
    218     }
    219     
    220     #print "file_exp:", $file_exp, "
    ";
    221     #print "txt_exp:", $txt_exp, "
    ";
    222     #print "###============================
    ";
    223     
    224     &ScanFold(".");
    225     
    226     print "如果想打开文件,则输入对应编号按回车
    ";
    227     
    228     my $num = <STDIN>;
    229     chomp $num;
    230  
    231     return if $num eq "";
    232         
    233     if ($num>=0 && $num<=$#scan_files) {
    234         my $path = getcwd;    #获取当前路径,用于获取文件的完整路径
    235         $path =~ s%/%\%g; #将/替换成
    236         
    237         my $file = $scan_files[$num];
    238         $file = substr($file, 1);  #去掉$file前面的.
    239         my $f = $path . $file;
    240          
    241         system "OpenInExplorer.exe $f";
    242     }    
    243     
    244 }
    245 
    246 sub Main {
    247     Scan @_;
    248 }
    grep

    同样为了方便,建立一个grep2.bat文件,其内容为(这里只所有取名为grep2,是因为本人在widnows中装了linux的一些软件后有grep程序了,为了不引起冲突而取名grep2)

    @echo off
    perl e:Toolsgrep.pl %*

    grep2 ClassName 查找所有文本文件中的ClassName

    grep2 -f file  只查找文件名(不查找内容)

    grep2 -f .cpp$ -t ClassName 在以.cpp结尾的文件中查找ClassName

    c. 从开源代码构建vs项目

    分析linux下的开源项目时往往没有IDE的支持,这里想要定位到变量的定义处,或者想查找在哪些地方有使用这个变量就很不方便。于是可以建立一个不能编译的vs项目,将所有源码添加到vs后,仅仅用来浏览代码。但基本上开源项目的结构都非常复杂,子文件夹中包括子文件夹,而vs也只支持批量添加同一个文件夹中的所有文件。如果一个个文件夹手动去添加代码文件,是个非常重复的工作。——于是程序的天性,消除重复劳动在此得到体现

    如果是建立c/c++项目,其项目拓展名是.vcproj,可以发现它就是一个xml文件。

    其包括文件的关键节点如下:

    <Files>
    <Filter Name="app">
    <File ReleativePath=".appabout.h">
    <File Releativepath=".appcpp.c">
    </Filter>
    <Files>

    知道了这个结构后,就可以用程序自动生成了~~

    文本操作,本人依然用Perl !!

     1 #
     2 #使用方法:将些文件复制到要建立VS项目的文件夹内,用perl create_vs.pl运行此文件。
     3 #           在运行前先vs_pre.txt复制到与create_vs.pl同目录下,这样就可以生成直接生成vcproj文件
     4 #
     5 
     6 use Win32::OLE;
     7 use warnings;
     8 use 5.010;
     9 
    10 use XML::Simple;
    11 use XML::DOM;
    12 
    13 #use XML::Tidy;
    14 use strict;
    15 use Encode;
    16 
    17 sub addFile;
    18 
    19 my $parser = new XML::DOM::Parser;
    20 my $doc    = $parser->parse('<Files/>');
    21 
    22 #addFile( 2, 4 );
    23 addFile( $doc->getDocumentElement(), '.' );
    24 $doc->printToFile('file.xml');
    25 $doc->dispose;
    26 
    27 open file_out, ">temp.vcproj";
    28 open file_in1, "vs_pre.txt";
    29 open file_in2, "file.xml";
    30 
    31 while(<file_in1>) {
    32     chomp($_);
    33     say file_out $_;
    34 }
    35 while(<file_in2>) {
    36     chomp($_);
    37     say file_out $_;
    38 }
    39 my $end ="     <Globals>
    40     </Globals>
    41 </VisualStudioProject>";
    42 say file_out $end;
    43 
    44 
    45 #下面的格式正则代码有问题
    46 #my $tidy = XML::Tidy->new( 'filename' => 'file.xml' );
    47 #$tidy->tidy();
    48 #$tidy->write();
    49 
    50 sub addFile {
    51     my $node = shift;
    52     my $path = shift;
    53 
    54     opendir( DIR, "$path" );
    55     my @file = readdir(DIR);
    56     closedir(DIR);
    57     foreach (@file) {
    58         next if $_ eq '.' or $_ eq '..';
    59         my $file = "$path\$_";
    60         if ( -d $file ) {
    61 
    62             #print $file,"
    ";
    63             my $n = $doc->createElement('Filter');
    64             my $att = $doc->createAttribute( 'Name', $_ );
    65             $n->setAttributeNode($att);
    66             $node->appendChild($n);
    67             addFile( $n, $file );
    68         }
    69         else {
    70             my $s = substr( $file, rindex( $file, "." ) );
    71             print $s,"
    ";
    72             #只添加h,c文件
    73             if ( $s ~~ /[h|hpp|cpp]/) {
    74                 my $n = $doc->createElement('File');
    75                 my $att = $doc->createAttribute( 'RelativePath', $file );
    76                 $n->setAttributeNode($att);
    77                 $node->appendChild($n);
    78             }
    79 
    80         }
    81     }
    82     #如果这个节点上没有子节点,则将其去掉
    83     if ( !$node->hasChildNodes() ) {
    84         $node->getParentNode()->removeChild($node);
    85     }
    86 }
    create.pl
    <?xml version="1.0" encoding="gb2312"?>
    <VisualStudioProject
        ProjectType="Visual C++"
        Version="9.00"
        Name="coreutils"
        ProjectGUID="{D5524811-7F7F-49A7-80E0-85645B1D2B68}"
        RootNamespace="coreutils"
        Keyword="Win32Proj"
        TargetFrameworkVersion="196613"
        >
        <Platforms>
            <Platform
                Name="Win32"
            />
        </Platforms>
        <ToolFiles>
        </ToolFiles>
        <Configurations>
            <Configuration
                Name="Debug|Win32"
                OutputDirectory="$(SolutionDir)$(ConfigurationName)"
                IntermediateDirectory="$(ConfigurationName)"
                ConfigurationType="1"
                CharacterSet="1"
                >
                <Tool
                    Name="VCPreBuildEventTool"
                />
                <Tool
                    Name="VCCustomBuildTool"
                />
                <Tool
                    Name="VCXMLDataGeneratorTool"
                />
                <Tool
                    Name="VCWebServiceProxyGeneratorTool"
                />
                <Tool
                    Name="VCMIDLTool"
                />
                <Tool
                    Name="VCCLCompilerTool"
                    Optimization="0"
                    PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
                    MinimalRebuild="true"
                    BasicRuntimeChecks="3"
                    RuntimeLibrary="3"
                    UsePrecompiledHeader="2"
                    WarningLevel="3"
                    DebugInformationFormat="4"
                />
                <Tool
                    Name="VCManagedResourceCompilerTool"
                />
                <Tool
                    Name="VCResourceCompilerTool"
                />
                <Tool
                    Name="VCPreLinkEventTool"
                />
                <Tool
                    Name="VCLinkerTool"
                    LinkIncremental="2"
                    GenerateDebugInformation="true"
                    SubSystem="1"
                    TargetMachine="1"
                />
                <Tool
                    Name="VCALinkTool"
                />
                <Tool
                    Name="VCManifestTool"
                />
                <Tool
                    Name="VCXDCMakeTool"
                />
                <Tool
                    Name="VCBscMakeTool"
                />
                <Tool
                    Name="VCFxCopTool"
                />
                <Tool
                    Name="VCAppVerifierTool"
                />
                <Tool
                    Name="VCPostBuildEventTool"
                />
            </Configuration>
            <Configuration
                Name="Release|Win32"
                OutputDirectory="$(SolutionDir)$(ConfigurationName)"
                IntermediateDirectory="$(ConfigurationName)"
                ConfigurationType="1"
                CharacterSet="1"
                WholeProgramOptimization="1"
                >
                <Tool
                    Name="VCPreBuildEventTool"
                />
                <Tool
                    Name="VCCustomBuildTool"
                />
                <Tool
                    Name="VCXMLDataGeneratorTool"
                />
                <Tool
                    Name="VCWebServiceProxyGeneratorTool"
                />
                <Tool
                    Name="VCMIDLTool"
                />
                <Tool
                    Name="VCCLCompilerTool"
                    Optimization="2"
                    EnableIntrinsicFunctions="true"
                    PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
                    RuntimeLibrary="2"
                    EnableFunctionLevelLinking="true"
                    UsePrecompiledHeader="2"
                    WarningLevel="3"
                    DebugInformationFormat="3"
                />
                <Tool
                    Name="VCManagedResourceCompilerTool"
                />
                <Tool
                    Name="VCResourceCompilerTool"
                />
                <Tool
                    Name="VCPreLinkEventTool"
                />
                <Tool
                    Name="VCLinkerTool"
                    LinkIncremental="1"
                    GenerateDebugInformation="true"
                    SubSystem="1"
                    OptimizeReferences="2"
                    EnableCOMDATFolding="2"
                    TargetMachine="1"
                />
                <Tool
                    Name="VCALinkTool"
                />
                <Tool
                    Name="VCManifestTool"
                />
                <Tool
                    Name="VCXDCMakeTool"
                />
                <Tool
                    Name="VCBscMakeTool"
                />
                <Tool
                    Name="VCFxCopTool"
                />
                <Tool
                    Name="VCAppVerifierTool"
                />
                <Tool
                    Name="VCPostBuildEventTool"
                />
            </Configuration>
        </Configurations>
        <References>
        </References>
    vs_pre.txt

    将create.pl vs_pre.txt复制到需要构建项目的地方,然后执行perl create.pl,这样就会生成一个temp.vcproj的项目,其中就包括了这个目录下所有的.h, .hpp, .cpp文件,在create.pl 的73行可以指定添加文件的类型。

     之前本人分析gimp和ffmpeg的源码就是用这种方法建立了vs项目,于是极大地提高了分析代码的效率

    如果以后有心情了,分析linux系统源码时也会用这种方式来构建项目。

     d. git项目的批量pull, push

    自从爱上了git.oschina.net后,将所有代码都放到git的私有项目中。c++代码都放在本地的 e:cpp_app 文件夹下

    如图所示,左下角有小绿圆圈的标志都是有提交git的项目。

    这么多项目,如果一个个手动地进入文件夹然后pull,push,非常繁琐。

    于是先建立下面的git_syn.pl文件

     1 my $one = $ARGV[0];
     2 my $path = "e:\cpp_app\";
     3 opendir(DIR, $path);
     4 my @files = readdir(DIR);
     5 
     6 foreach (@files) {
     7     next if $_ eq '.' or $_ eq '..';
     8         
     9     my $str = $path . $_ . "\" . ".git";
    10     if (-d $str) {
    11         my $s = $path . $_;
    12 
    13         say "
    
    =============== now directory : $s";
    14         chdir $s;
    15 
    16         if ($one == 0) {
    17             system "git add .";
    18             system "git commit -a";
    19             system "git push";
    20         } elsif ($one == 1) {
    21             system "git pull";
    22         }
    23     }
    24 }

    建立pull.bat文件

    1 echo off
    2 perl git_syn.pl 1
    3 pause

    建立push.bat文件

    1 echo off
    2 perl git_syn.pl 0
    3 pause

     git_syn.pl遍历e:cpp_app文件夹下的所有文件夹,如果发现有.git子文件夹,则根据传入参数判断是push还是pull操作。

    有了pull.bat, push.bat后,妈妈再也不会担心有代码没更新了。使用svn的项目也这样弄,只要将git 改成svn,pull,push换成update,commit即可。参见《命令行&界面

    5. 正则表达式

    个人认为程序员应该将正则表达式融入自己的血液

    如果不沉下心来学习,或者学了后不用,都会出现想使用正则表达式而很茫然的情况。

    本人借着学习Perl的机会,将正则表达式重新好好学了一遍,并且在日常的工作中有意识地强迫自己去使用,几个月下来后基本上可以称得上熟练掌握了正则表达式。

    下面就介绍几个在vs中用正则表达式进行查找/替换的例子(vs的正则和标准的正则有所不同,不过思想是一样的,只是在表示符号上不所不同):

    用如下图所示的方法打开vs的正则表达式查找、替换功能:

    • 查找被注释掉的代码   .*//.*GetTickCount
    • 将for,if, while后面的 { 放在与其同一行。查找部分为 ^{:b*[for|if|while].*[^{]} :b*{  替换为 1{
    • 给所有逗号后面都加上一个空格。查找部分为,{[^ ]},替换为, 1

     其中{}表示分组(相当于标准正则中的()),[]表示一类字符集(相当于标准正则中的{})

    关于正则表达式的具体使用情况还有很多,结合上面介绍的grep2,可以用.cpp$来查找所有后缀是cpp的文件。

    总之,学习正则表达式的回报会随着时间的累积越来越多,随着对其掌握的熟练程序而越来越多。

  • 相关阅读:
    CVS,GIT,Mercurial和SVN比较
    ubuntu-使用终端配置网络
    编写简单的hashCode方法
    编写高质量equals方法
    文件上传和下载
    Java常用命令
    增删查改-MySQL
    Newton迭代法-C++
    二分法-C++
    适配器模式
  • 原文地址:https://www.cnblogs.com/xiangism/p/4571651.html
Copyright © 2011-2022 走看看