处理emacs-org模式TODO的一个脚本
处理前:
处理后:
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;