处理前:
处理后:
1 前言
最近风帆问我一个问题,也就是处理org模式中的TODO。写一个脚本, 主要功能是未完成的按照“重要性”与“紧急性”进行分类。然后完成的 任务列出最近一周完成的。感觉还听有用的,我自己也经常用org模式 所以用了一晚上的时间,写了这个脚本,然后上午来了以后由修改了 一下。基本算是可以用了。在写这个脚本的过程中,通过遇到的问题 从中又学习了几点。总结一下,方便后来查看。
2 中文的处理
Perl处理中文会遇到乱码的问题。我用的vim编辑器也有编码的问题。 这里一并总结一下。
2.1 vim相关
在vim中直接查看文件编码: :set fileencoding
解决vim查看文件乱码的问题:在~/.vimrc中添加一下内容:
let &termencoding=&encoding
set fileencoding=utf-8,ucs-bom,gbk,cp936
这样vim就可以自动识别编码。
2.2 perl 相关
网址:wyllife.blog.163.com/blog/static/4116390120112152541260
Perl实用中文处理步骤(修改版)
2011-03-15 14:05:41| 分类: PERL 相关知识 |字号 订阅 发信人: FenRagwort (泽), 信区: Perl 标 题: Perl实用中文处理步骤(修改版) 发信站: 水木社区 (Mon Feb 14 12:52:14 2011), 转信
(修改版 感谢Invader)
0、你至少得知道编码是怎么回事,utf-8、gbk是什么意思 你的文本编辑器能显示一个文件是什么编码, 不然你要处理中文文件,都不知道用什么编码打开 不过一般就是gbk和utf8两种,实在不行两个都试一遍 注意也许你看到的不是gbk,而是gb2312, 这两个使用上实际是一样的,gbk完全包含gb2312
1、让你的脚本文件本身用utf8保存,最好养成写任何脚本都用utf8的习惯
2、脚本开头加上: use utf8; use open ":encoding(gbk)", ":std"; 意思是脚本里的字符串都用utf8处理,但是标准输入输出用gbk(默认的代码页编码) 做到这一步,脚本里就可以直接用中文了,字符串、正则表达式都没问题
如果要打开的文件全部是一种编码,如utf8,则可以加上: use open ":encoding(utf8)"; #如果文件全是gbk,那么承上编码设置,此行可省略
3.1、打开内有中文的文件前,先要确定它的编码, 最常见是gbk或utf8,*来的可能是big5,utf16le的偶有可能,其他较少见 这样打开: open my $fh, "<:encoding(gbk)", "file.txt" or die; # 读文件 open my $fh, ">:encoding(utf8)", "file.txt" or die; # 写文件
如果Win32系统下打开utf16le或be文件,需要写成: open my $fh, "<:raw:encoding(utf16le):crlf", "file.txt" or die; 否则会有crlf转换的bug
3.2、也可以先打开文件,立刻再用binmode绑定编码 open my $fh, "file.txt" or die; binmode($fh, ":encoding(gbk)"); 一般情况,直接在open里指定encoding即可,有时需要先接收数据,再binmode
4、如果你的文件名是中文,有点麻烦,得这样: use Encode qw/encode/; my $file = "2011年工作记录.txt"; # 中英文数字混合文件名也没问题 $file = encode("gbk", $file); # 文件名是通过标准输出传给命令行的,而命令行 open my $fh, "<:encoding(gbk)", $file or die;
OK,中文问题搞定了,然后该干嘛干嘛,除了一些以字节为对象的操作(如seek、pack), 你就把“甲乙丙丁”当“ABCD”用吧,冇问题
X、附送小技巧: 如果你是批量处理文本文件,那甚至可以不管中文文件名问题 比如要处理chfiles文件夹下的所有txt文件(包含中文文件名),那么 my @files = glob "chfiles/*.txt"; foreach my $file (@files) { # $file若print出来可能有乱码,但是无妨 open my $fh, "<:encoding(gbk)", $file or die; while (<$fh>) { print; } }
3 时间相关
直接在下面程序中解释 包括本地的时间函数localtime,和一个模块,Date::Calc来求两个时间点的天数差。
4 程序解析
1: use strict;
2: use warnings;
3: use utf8;
4: use Encode;
5: use open ":encoding(utf8)",":std";
6: use Date::Calc qw(Delta_Days);
7: use Date::Calc qw(Add_Delta_Days);
8: use Data::Dumper;
9:
10: my (%hash,%hash_finished,$renwu,$start_time);
11: my $in_in = "TODO.org";
12: open my $in, '<', $in_in or die "cannot open\n";
13: while(<$in>)
14: {
15: chomp;
16: my $first_line=$_;
17: next if /^#/;
18: next if /^$/;
19: if ($first_line=~m/^\* TODO/)
20: {
21: if ($first_line=~m/^\* TODO(.+):重要紧急:/)
22: {
23: $hash{"重要紧急"}{$1}="A";
24: }
25: elsif($first_line=~m/^\* TODO(.+):重要不紧急:/)
26: {
27: $hash{"重要不紧急"}{$1}="A";
28: }
29: elsif($first_line=~m/^\* TODO(.+):不重要紧急:/)
30: {
31: $hash{"不重要紧急"}{$1}="A";
32: }
33: elsif($first_line=~m/^\* TODO(.+):不重要不紧急:/)
34: {
35: $hash{"不重要不紧急"}{$1}="A";
36: }
37: }
38: elsif($first_line=~/^\* DONE/)
39: {
40: $first_line=~/^\* DONE (.+)?\s+:.+:/;
41: $renwu=$1;
42: my $second_line=<$in>;
43: chomp $second_line;
44: $second_line=~m/^CLOSED: \[([-\d]+).+]/;
45: my $third_line=<$in>;
46: $third_line=~m/^.+\[(.+).....]/;
47: $start_time=$1;
48: $hash_finished{$renwu}{$start_time}{$second_line}="A";
49: }
50: }
51: close $in;
52:
53:
54: my $out_out = "dayreport.org";
55: open my $out, '>', $out_out or die "failed open$!\n";
56:
57: print $out "#+STARTUP: showall\n";
58: print $out "#+TITLE:TODO\n";
59: print $out "#+HTML_HEAD: <link rel=\"stylesheet\" type=\"text/css\" href=\"todo.css\" />\n";
60: print $out "#+OPTIONS: H:3 num:nil toc:nil \\n:t \@:t ::t |:t ^:nil -:t f:t *:t \\<:t\n";
61: print $out "#+LANGUAGE: en\n";
62:
63: =cut
64: foreach my $key1 (keys %hash)
65: {
66: print $out "* $key1\n";
67: foreach my $key2 (keys %{$hash{$key1}})
68: {
69: print $out " - $key2\n";
70: }
71: }
72: =cut
73: print $out "* 重要紧急\n";
74: foreach my $key2 (keys %{$hash{"重要紧急"}})
75: {
76: $key2=~s/\s+$//;
77: print $out " - $key2\n";
78: }
79: print $out "* 重要不紧急\n";
80: foreach my $key2 (keys %{$hash{"重要不紧急"}})
81: {
82: $key2=~s/\s+$//;
83: print $out " - $key2\n";
84: }
85: print $out "* 不重要紧急\n";
86: foreach my $key2 (keys %{$hash{"不重要紧急"}})
87: {
88: $key2=~s/\s+$//;
89: print $out " - $key2\n";
90: }
91: print $out "* 不重要不紧急\n";
92: foreach my $key2 (keys %{$hash{"不重要不紧急"}})
93: {
94: $key2=~s/\s+$//;
95: print $out " - $key2\n";
96: }
97:
98: #follow is the number of today
99: my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
100: $mon=$mon+1;
101: $year+=1900;
102: #周一是从周日开始的,要进行一下改动
103: if ($wday==0)
104: {
105: $wday=$wday+7;
106: }
107: print $wday;
108: my %hash_day=(
109: 周日 => "0",
110: 周一 => "1",
111: 周二 => "2",
112: 周三 => "3",
113: 周四 => "4",
114: 周五 => "5",
115: 周六 => "6",
116: );
117:
118: #用程序计算每周的起止时间,用到Date::Calc模块
119: my ($monday_year,$monday_mouth,$monday_day);
120: ($monday_year,$monday_mouth,$monday_day)=Add_Delta_Days($year,$mon,$mday,-$wday+1);
121: my ($sunday_year,$sunday_mouth,$sunday_day);
122: ($sunday_year,$sunday_mouth,$sunday_day)=Add_Delta_Days($year,$mon,$mday,7-$wday);
123:
124: print $out "\n* 本周已经完成任务: <$monday_year-$monday_mouth-$monday_day>-<$sunday_year-$sunday_mouth-$sunday_day>\n";
125: foreach my $key1 (keys %hash_finished)
126: {
127: foreach my $key2 (keys %{$hash_finished{$key1}})
128: {
129: foreach my $key3 (keys %{$hash_finished{$key1}{$key2}})
130: {
131: #print "$key3\n";
132: $key3=~m/^CLOSED: \[(\d+)-0?(\d+)-0?(\d+) (.+) .+]/;
133: my $before_year=$1;
134: my $before_mon=$2;
135: my $before_mday=$3;
136: my $before_weekday=$4;
137: #print "$before_weekday\n";
138: #用模块来计算两个时间相差的天数
139: my $gap=Delta_Days($before_year,$before_mon,$before_mday,$year,$mon,$mday);
140: #print "$gap\n";
141: my $weekday=$hash_day{$before_weekday};
142: #print "$weekday\n";
143: if ($weekday <= $wday and $gap <= 7)
144: {
145: $key1=~s/\s+/\t/g;
146: print $out " - $key1 SCHEDULED:<$key2>\t$key3\n";
147: }
148: else
149: {
150: next;
151: }
152: }
153: }
154: }
155:
156: close $out;