Chinaunix首页 | 论坛 | 博客
  • 博客访问: 392376
  • 博文数量: 117
  • 博客积分: 4416
  • 博客等级: 上校
  • 技术积分: 1135
  • 用 户 组: 普通用户
  • 注册时间: 2009-06-08 14:16
个人简介

一生醉生忘死,就让他继续下去吧!

文章分类

全部博文(117)

分类: LINUX

2012-11-12 15:30:32

 

点击(此处)折叠或打开

  1. #!/usr/bin/perl
  2. ############AJ##############
  3. $input=@ARGV[0];
  4. open DF,"<$input";
  5. open KF,">aj" ;
  6. open MF,">aj_temp";
  7. open ER,">error_aj";
  8. my $format="%-10s %-10s %-150s %-10s %-10s %-10s %-10s %-10s %-40s %-40s %-10s %-10s %-10s %-10s";
  9. while (<DF>) {
  10. if ($_=~/^([^\t]+)\t([^\t]*)\t{2}([^\t]+)\t(\d+)\t(\d{6})(\d{6})\t([ABCDEFG])\t{2}(\d+)\t{2}([^\t]*)\t{3}\d*\\{0,1}([^\t]*)\t{3}(\d{4})\t(\d+)\t{3}([^\t]*)\t{4}[^\t]*\t{4}([^\s]*)/)
  11. {
  12.     printf KF $format,$1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14;
  13.     print KF "\n";
  14.     printf MF $format,$1,$2,$12;
  15.     print MF "\n";
  16. }
  17. else {
  18.         print ER $.,".\n";
  19.         
  20. }
  21. }
  22. close DF;
  23. close KF;
  24. close MF;
  25. close ER;
  26. ###########JN###############
  27. $gbk=$ARGV[1];
  28. $utf="utf_jn";
  29. `iconv -f gbk -t utf8 $gbk -o $utf`;
  30. open DF,";
  31. open KF,">jn1";
  32. my $text;
  33. while (<DF>) {
  34.     $text.=$_;
  35. }
  36. $text=~s/\s*\n"//g; ######为什么用\s,不用\t
  37. $text=~s/\n\r//g;
  38. $text=~s/\r\t/\t/g;
  39. $text=~s/\t"\t/\t\t/g;######替换以引号开头的行
  40. $text=~s/\t{3}"/\t\t\t/g;
  41. $text=~s/(\d{1,3})-|—(\d{1,3})/$1-$2/g; ######替换两种标点符号
  42. $text=~s/\n([^\t]+)/$1/g; #####替换行头没有\t的行
  43. print KF $text;
  44. close DF;
  45. close KF;

  46. `iconv -f utf8 -t gbk jn1 -o gbk_jn`;
  47. open DF,"<gbk_jn";
  48. open KF,">jn" ;
  49. open ER,">error_jn";
  50. my $format="%-40s %-250s %-10s %-10s %-40s %-10s %-10s %-10s %-10s %-10s %-10s";
  51. while () {
  52. if ($_=~/^\t([^\t]*)\t{2}([^\t]*)\t(\d{4}-\d{1,}-\d{1,})*[^\t]*\t{5,}([A|B|C|D|E|F|G])\t([^\t]*)\t{3,}(\d+)-(\d+) *\t{2}[ |\t]{0,1}([^\t]*)\t(\d+)\t{5}(\d+)\t(\d+)\t{2}/)
  53. {
  54.     printf KF $format,$1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11;
  55.     print KF "\n";
  56. }
  57. elsif ($_=~/^\t([^\t]*)\t{2}([^\t]*)\t(\d{4}-\d{1,}-\d{1,})*[^\t]*\t{5,}([A|B|C|D|E|F|G])\t([^\t]*)\t{3,}(\d*) *\t{2}[ |\t]+([^\t]*)\t(\d+)\t{5}(\d+)\t(\d+)\t{2}/)
  58. {

  59.     printf KF $format,$1,$2,$3,$4,$5,$6,$6,$7,$8,$9,$10;
  60.     print KF "\n";
  61. }
  62. else {
  63.         print $.,".\n";
  64.         print ER "$.===$_";
  65. }

  66. }
  67. close DF;
  68. close KF;
  69. close EF;


  70. ##########merge##################
  71. open AJ,"<aj_temp";
  72. open JN,"<jn";
  73. open OUT,">result";
  74. while ()
  75. {
  76. ($a,$b,$c)=split(/\s+/,$_);
  77. $hash{$c}="$a $b";
  78. }
  79. #        print "$keys\n
  80. while ()
  81.    {
  82. # ($a,$b,$c,$d,$e,$f,$g,$h,$i,$j,$k,$l,$m)
  83. =split(/\s+/,$_);
  84.    for $keys (keys %hash) {
  85.                              if ($_=~/.*\b$keys\b.*/) {  #####当前行是否包含键值
  86.          s/^/$hash{$keys}/;
  87.          print OUT $_;
  88.        }
  89. }
  90. }

aj=================

点击(此处)折叠或打开

  1. #!/usr/bin/perl
  2. open DF,"<2007aj.TXT" ;
  3. open KF,">aj.txt" ;
  4. open MF,">aj_temp.txt";
  5. my $format="%-10s %-10s %-150s %-10s %-10s %-10s %-10s %-10s %-40s %-40s %-10s %-10s %-10s %-10s";
  6. while (<DF>) {
  7. if ($_=~/^([^\t]+)\t([^\t]*)\t{2}([^\t]+)\t(\d+)\t(\d{6})(\d{6})\t([ABCDEFG])\t{2}(\d+)\t{2}([^\t]*)\t{3}\d*\\{0,1}([^\t]*)\t{3}(\d{4})\t(\d+)\t{3}([^\t]*)\t{4}[^\t]*\t{4}([^\s]*)/)
  8. {
  9.     printf KF $format,$1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14;
  10.     print KF "\n";
  11.     printf MF $format,$1,$2,$12;
  12.     print MF "\n";
  13. }
  14. else {
  15.         print $.,".\n";
  16. }

  17. }





jn=========================

点击(此处)折叠或打开

  1. #!/usr/bin/perl
  2. open DF,"<2000jn.TXT" ;
  3. open KF,">jn.txt" ;
  4. my $format="%-40s %-200s %-10s %-10s %-40s %-10s %-10s %-10s %-10s %-10s %-10s";
  5. while (<DF>) {
  6. if ($_=~/^\t([^\t]*)\t{2}([^\t]*)\t(\d{4}-\d{1,}-\d{1,})*[^\t]*\t{5,}([A|B|C|D|E|F|G])\t([^\t]*)\t{4,}(\d+)-(\d+) *\t{2}[ |\t]+([^\t]*)\t(\d+)\t{5}(\d+)\t(\d+)\t{2}/)
  7. {
  8.     printf KF $format,$1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11; #####不同数字
  9.     print KF "\n";
  10. }
  11. elsif ($_=~/^\t([^\t]*)\t{2}([^\t]*)\t(\d{4}-\d{1,}-\d{1,})*[^\t]*\t{5,}([A|B|C|D|E|F|G])\t([^\t]*)\t{4,}(\d+) *\t{2}[ |\t]+([^\t]*)\t(\d+)\t{5}(\d+)\t(\d+)\t{2}/)
  12. {
  13.     printf KF $format,$1,$2,$3,$4,$5,$6,$6,$7,$8,$9,$10;  #####相同数字
  14.     print KF "\n";
  15. }
  16. else {
  17.         print $.,".\n";
  18. }

  19. }




merge.pl

点击(此处)折叠或打开

  1. #!/usr/bin/perl
  2. open AJ,";
  3. open JN,";
  4. open OUT,">b.txt";
  5. while (<AJ>)
  6. {
  7. ($a,$b,$c)=split(/\s+/,$_);
  8. $hash{$c}="$a $b";      #########以$c为键值创建哈希
  9. }
  10. #        print "$keys\n";
  11.         while (<JN>)
  12.             {
  13. #                    ($a,$b,$c,$d,$e,$f,$g,$h,$i,$j,$k,$l,$m)=split(/\s+/,$_);
  14.                     for $keys (keys %hash) {
  15.                             if ($_=~/.*\b$keys\b.*/) {  #####当前行是否包含键值
  16.                                     s/^/$hash{$keys} /;
  17.                                     print OUT $_;
  18.                             }
  19. }
  20. }



合并2个文件的所有列============================================

点击(此处)折叠或打开

  1. #!/usr/bin/perl

  2. open(T,"a.txt");
  3. my @content1 = <T>;
  4. chomp(@content1);
  5. close T;
  6. open(TT,"b.txt");
  7. my @content2 = <TT>;
  8. chomp(@content2);
  9. close TT;
  10. my $len1 = scalar(@content1);
  11. my $len2 = scalar(@content2);
  12. my $num = $len1 > $len2 ? $len1-1:$len2-1;
  13. open(T1,">c.txt");
  14. for (0..$num) {
  15.                 print T1 "$content1[$_]$content2[$_]\n";
  16. }
  17. close T1;
  18. <STDIN>;


 

 

 

 

 


如何对文本的列进行操作,下面是仙子的举例,看得头痛阿

简简单单讲map


(一)map函数

map BLOCK LIST
map EXPR, LIST

map函数对LIST里的每个元素按BLOCK或EXPR进行计算,遍历LIST时,临时将LIST里的每个元素赋值给$_变量。map对每次的计算返回一个结果列表,它在列表上下文里计算BLOCK或EXPR。每个LIST元素可能在输出列表里产生0个,1个,或多个元素。

(仙子注:上文是说遍历每个LIST元素时产生一个结果列表,而不是说总的map结果是个列表,不要搞混了哦。)

在标量上下文里,map返回结果列表的元素数量。在HASH上下文里,输出列表(a,b,c,d...)会变成这样的形式: ( a =>; b, c =>; d, ... )。假如输出列表的元素数量非对称,那么最后的hash元素的值就是undef了。

避免在BLOCK或EXPR里修改$_,因为这会修改LIST里的元素。另外,避免使用map返回的的列表作为左值,因为这也会修改LIST里的元素。(所谓左值,就是在某个表达式左边的变量。)


(二)Map vs. grep vs. foreach

map跟grep一样,从数组里选择元素。下列2句是一样的:

@selected = grep EXPR, @input;
@selected = map { if (EXPR) { $_ } } @input;

另外,map也是foreach陈述的特殊形式。假如@transformed数组当前未定义或为空,那么下列2句亦相等:

foreach (@input) { push @transformed, EXPR; }
@transformed = map EXPR, @input;

通常,用grep来从数组里选择元素,用map来从数组里转换元素。当然,数组处理也能使用标准的循环语句来完成(foreach, for, while, until, do while, do until, redo)。


(三)map用法示例

1. 转换文件名为文件大小

@sizes = map { -s $_ } @file_names;

-s是个文件测试操作符,它返回某个文件的size。所以上面这句就返回@file_names数组里每个文件的大小,结果也是个数组。

2. 转换数组到hash:找到某个数组值的索引

代替重复的搜索数组,我们可以用map来转换数组到hash,并通过hash关键字来进行直接查找。如下的map用法相对于重复的数组搜索,更简单高效。

@teams = qw(Miami Oregon Florida Tennessee Texas
            Oklahoma Nebraska LSU Colorado Maryland);
%rank = map { $teams[$_], $_ + 1 } 0 .. $#teams;
print "Colorado: $rank{Colorado}\n";
print "Texas: $rank{Texas} (hook 'em, Horns!)\n";

打印结果是:
Colorado: 9
Texas: 5 (hook 'em, Horns!)

上述code容易理解哦,0 ..$#teams 是个列表,$#teams代表@teams最后一个元素的下标值(这里是9),所以这个列表就是0-9这几个数了。map遍历上述列表,将每个列表元素临时设置为$_,并对$_在中间的{}里进行计算;{ $teams[$_], $_ + 1 },这里每次计算后返回一个2元素的列表,列表结果是某个数组值和对应的数组下标加1,明白了呀?

由于对每个LIST元素进行计算时,都产生一个2元素的列表,所以总的map结果就可看作一个hash了。hash关键字就是数组元素,hash值是对应的数组下标加1。

3. 转换数组到hash:查找拼错单词

转换数组到hash是map的最普遍用法。在本示例里,hash的值是无关紧要的,我们仅检查hash关键字是否存在。

%dictionary = map { $_, 1 } qw(cat dog man woman hat glove);
@words = qw(dog kat wimen hat man gloove);
foreach $word (@words) {
    if (not $dictionary{$word}) {   
        print "Possible misspelled word: $word\n";
    }
}

打印结果是:
Possible misspelled word: kat
Possible misspelled word: wimen
Possible misspelled word: gloove

看看第1句的map用法,它跟前面示例里的差不多哦。qw()这里是个列表,map对这个列表里的每个元素进行{ $_, 1 }计算,每次计算的结果返回一个2元素的列表,换句话说,就是%dictionary的key和value呀。所以map最终的结果就是一个hash了,关键字是qw()里的元素,值总是1,无关紧要的。

然后下面的foreach语句就容易了哦,如果@words里的元素不构成%dictionary的关键字的话,就打印一条出错消息。如果把%dictionary看成标准字典的话,那么就可用它来检验你自己的@words字库里是否有错字了呀。

4. 转换数组到hash:存储选中的CGI参数

hash通常是存储传递给程序或子函数的参数的最便利的方法,而map通常是创建这个hash的最便利的方法。

use CGI qw(param);
%params = map { $_, ( param($_) )[0] }
              grep { lc($_) ne 'submit' } param();


这里你可能要了解一下CGI模块的基本知识哦。param()调用返回CGI参数名的列表;param($_)调用返回指定的CGI参数名的值。假如param($_)返回某个CGI参数的多个值,那么( param($_) )[0]只取第一个值,以便hash仍被良好定义。

上述code的意思是,将param()的结果作为输入列表,它的元素是多个CGI参数名,然后从这些参数名里grep出参数名不等于'submit'的,结果是一个临时列表,map的{ $_, ( param($_) )[0] }语句再次遍历这个临时列表,并获取到参数名,和对应的参数值,将结果赋给%params。所以%params里就存储了页面提交过来的,除了submit外的其他CGI参数名和参数值(只取第1个)。

很巧妙的用法,是不是?它结合用了map和grep,使code显得很简洁。

(话外一句:偶在Cornell读书时,偶的师兄们很喜欢这种用法,他们往往在中间多次使用map,grep,sort进行堆叠,结果产生的code也许高效,但不容易看懂。读这样的code时,你要从右往左读,因为右边表达式产生的临时列表,是左边表达式的输入条件。)

5. 产生随机密码

@a = (0 .. 9, 'a' .. 'z');
$password = join '', map { $a[int rand @a] } 0 .. 7;
print "$password\n";

每次运行它会得到不同的结果,但长度总是8位,由0 .. 7这个决定。如下是可能的输出:

y2ti3dal

它是个随机值,也许你能用它来做密码。

这里,需要先明白几个函数,rand产生一个随机值,它后面的@a其实是个标量哦,表示@a数组的长度,rand @a的结果可能是个小数,所以再用int函数来取整。int rand @a的结果是个整数,它>;=0但小于@a的长度。所以$a[int rand @a]就表示从@a数组里随机取出一个字符了。0..7表示总共取8次,返回的结果再用join连接起来,就构成一个8位随机密码了呀。

当然,(0 .. 9, 'a' .. 'z')数组元素太少了,你可以修改它,使其包含大小写字符,数字和标点符号,这样密码强度就高些。

6. 从数组元素里剥离数字

已经说了哦,不要在EXPR里修改LIST值。如下做法是不好的:

@digitless = map { tr/0-9//d; $_ } @array;  

它虽然从数组元素里剥离了数字,但同样破坏了该数组,:(

如下做法是good:

@digitless = map { ($x = $_) =~ tr/0-9//d;   
                   $x;
                 } @array;

它将tr的结果赋给临时变量$x,并返回$x的值,这样就保护数组了呀。

7. 打印"just another perl hacker",让你晕到家

print map( { chr }
           ('10611711511603209711011111610410111' .
           '4032112101114108032104097099107101114')
           =~ /.../g
         ), "\n";

打印的结果是:
just another perl hacker

chr函数将单个数字转换到相应的ASCII字符。()=~/.../g语法以3个数字长度为单位,分割数字串到新的串列表。

比较无聊的用法,还不如用pack()和unpack(),:P

8. 转置矩阵

@matrix = ( [1, 2, 3], [4, 5, 6], [7, 8, 9] );
foreach $xyz (@matrix) {
    print "$xyz->;[0]  $xyz->;[1]  $xyz->;[2]\n";
}
@transposed =
    map { $x = $_;
          [ map { $matrix[$_][$x] } 0 .. $#matrix ];
        } 0 .. $#{$matrix[0]};
print "\n";
foreach $xyz (@transposed) {
    print "$xyz->;[0]  $xyz->;[1]  $xyz->;[2]\n";

打印结果是:

1  2  3
4  5  6
7  8  9

1  4  7
2  5  8
3  6  9

这里稍微有点复杂哦,让我们分2步看看。

@matrix = ( [1, 2, 3], [4, 5, 6], [7, 8, 9] );
foreach $xyz (@matrix) {
    print "$xyz->;[0]  $xyz->;[1]  $xyz->;[2]\n";
}

这里不难明白,( [1, 2, 3], [4, 5, 6], [7, 8, 9] ) 是个数组,它的每个元素又是个匿名数组,这样在$xyz遍历数组时,$xyz->;[0],$xyz->;[1],$xyz->;[2]就可以访问到匿名数组里的元素了。所以会打印出:

1  2  3
4  5  6
7  8  9

@transposed =
    map { $x = $_;
          [ map { $matrix[$_][$x] } 0 .. $#matrix ];
        } 0 .. $#{$matrix[0]};

这里复杂点,0 .. $#{$matrix[0]}是个列表,$#{$matrix[0]}表示$matrix[0]这个匿名数组的最大下标值,0 .. $#{$matrix[0]}表示矩阵的横向。$x = $_;这里将$_的值赋给$x,为什么呢?因为它后面又有个map嘛,$_的值会改变的,所以要先存储起来。外围的map返回的值是[]里的map计算出来的一个列表,以[]匿名数组形式返回。[]里面的map是这样的,它的输入LIST是0 .. $#matrix, 表示矩阵的纵向了。$matrix[$_][$x]这里先纵再横,就把矩阵值置换了一下。所以返回的结果列表@transposed就包含置换后的矩阵了哦。

是否有点糊涂?那举例看看。这样看可能好点:

[1, 2, 3],
[4, 5, 6],
[7, 8, 9]

外围的map遍历时,先是横向下标遍历,停留在横向0位。然后第二个map,就是纵向下标遍历了,它要遍历所有纵向下标,这样在横向0位,就先返回[1,4,7]的列表了,然后在横向1位,又返回[2,5,8]的列表,最后在横向2位,返回[3,6,9]的列表。

还不明白呀?那偶也讲不清了,自己多想想,:P

9. 查找质数:警示用法

foreach $num (1 .. 1000) {
    @expr = map { '$_ % ' . $_ . ' &&' } 2 .. int sqrt $num;
    if (eval "grep { @expr 1 } $num") { print "$num " }
}

打印结果是:
1 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 ...

该code能工作,但它如此麻烦,违背了程序最基本的明晰法则。用如下直观的code代替它就可以了呀:

CANDIDATE: foreach $num (1 .. 1000) {
    foreach $factor (2 .. int sqrt $num) {
        unless ($num % $factor) { next CANDIDATE }
    }
    print "$num ";
}

记住,让你的Code简洁哦~~

阅读(2071) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~