如果要用Perl来查一个文件有多少行,怎么办?Perl Cookbook里的Counting Lines (or Paragraphs or Records) in a File就给我们讲了一些方法。
在Windows下,可以配合Cygwin里的wc来得到结果。如果你的Cygwin里已经装了wc,则直接用下面的程序就可以得到你想要的结果:
$count = `wc -l < $file`;
die “wc failed: $?” if $?;
chomp($count);
当然,如果你喜欢的话,也可以直接打开文件,一行一行地读入文件,然后得到文件的行数。
open(FILE, “< $file”) or die “can’t open $file: $!”;
$count++ while <FILE>;
# $count now holds the number of lines read
如果你的行是以“\n”结尾的话,可以这样写:
$count += tr/\n/\n/ while sysread(FILE, $_, 2 ** 16);
当然,你也可以模拟wc的形式来写这些代码,下面就是一种形式:
open(FILE, “< $file”) or die “can’t open $file: $!”;
$count++ while <FILE>;
# $count now holds the number of lines read
更加简洁的形式:
open(FILE, “< $file”) or die “can’t open $file: $!”;
for ($count=0; <FILE>; $count++) { }
还有一种更酷的写法:
1 while <FILE>;
$count = $.;
如果你要数一数有多少个段落,就参考这个代码吧:
$/ = ”; # enable paragraph mode for all reads
open(FILE, $file) or die “can’t open $file: $!”;
1 while <FILE>;
$para_count = $.;
平时删除行都是用C-k,当然,如果要删除光标到行尾的内容,直接用C-k就行了;但是如果光标不在行首时,要删除整行,则要先用C-a移到行首,然后再C-k删除整行。在删除操作不算太频繁的情况下,倒也还凑合。
可是,最近在关task的时候,在公司的信息系统里关闭了task,还要在自己备份的txt文件里删掉这个task。由于查找等各个方面的原因,光标不可能时时刻刻停留在行首。所以用C-k来删除行的时候,往往要先用一个C-a来把光标移动到行首。在这种删除任务相对密集的情况下,多用好多次C-a真是添加了太多的麻烦!
碰到这种情况,可以有两种方法:
1) C-S-backspace (kill-whole-line)
你按C-S-backspace键,即命令kill-whole-line就可以把光标所在行全部删掉,这已经是Emacs预定义好的了。
当然,相信大多数人会觉得这种方法比较麻烦,我也是。
2) 改造你的C-w和M-w键
把下面的代码扔到.emacs里:
(defadvice kill-ring-save (before slickcopy activate compile)
“When called interactively with no active region, copy a single line instead.”
(interactive
(if mark-active (list (region-beginning) (region-end))
(list (line-beginning-position)
(line-beginning-position 2)))))(defadvice kill-region (before slickcut activate compile)
“When called interactively with no active region, kill a single line instead.”
(interactive
(if mark-active (list (region-beginning) (region-end))
(list (line-beginning-position)
(line-beginning-position 2)))))
这样,当你没有选中一个区域的时候,C-w会剪切光标所在行,不管光标的位置在哪里;而用M-w的时候,则会复制光标所在的行,不管光标的位置在行首还是行尾还是行中间的任意位置。当你有选中区域的时候,C-w和M-w的功能和Emacs自带的没啥两样。
是不是觉得更加方便了?
经常要贴自己的代码给别人看,自然,就非常希望让别人看到自己在Emacs中精心配置好的颜色、代码风格,以便于阅读、理解代码。不过,这似乎有点难度。现在好了,用上htmlize.el这个扩展,就可以把代码当前的颜色、代码风格,直接转化为html页面。这样,别人看起来会舒服很多,当别人认为你的代码有用的时候,再叫你拿txt文件也不迟。
可以先看看作者的例子,htmlize.el.html就是htmlize.el的彩色显示,这样,可读性是不是比纯文本的htmlize.el强多了?
把htmlize.el扔到你的path里,并在.emacs里加入以下语句即可:
;; set htmlize
(require ‘htmlize)
这个扩展可以有如下几种使用方法:
1) M-x htmlize-buffer
把当前的buffer转为一个html文件,并保留当前你Emacs的色彩定义。运行这个命令后,Emacs会跳转到一个新的buffer里,你把这个buffer保存下来即可。
2) M-x htmlize-file
这个命令会在mini-buffer里提示输入你需要转换的文件,自动帮你转换好,并保存为.html。
3) M-x htmlize-many-files
这个命令和2)差不多的功能,不过可以让你同时转一批文件。
4) M-x htmlize-many-files-dired
这个命令可以把你标记好的目录下的所以文件都转成html。
今天在水木社区上看到recent-jump1.zip这个扩展,觉得蛮有用的。
我们在Emacs里编辑文章的时候,经常会有一些大的跳转。比例说,跳转到buffer的开头,查找等。如果能够快速地跳回到开始的地方,那将十分的方便。
比如说,当我们在写程序代码的时候,我们经常要查一些手册、参考资料什么的,然后再回到我们写代码的地方。如何能方便快速地实现这个功能呢?
recent-jump.el就提供了这样的一个简洁方法。先把recent-jump.el扔到你的path里,然后把下面这些加入到.emacs里:
;; set recent-jump
(setq recent-jump-threshold 4)
(setq recent-jump-ring-length 10)
(global-set-key (kbd “C-o”) ‘recent-jump-jump-backward)
(global-set-key (kbd “M-o”) ‘recent-jump-jump-forward)
(require ‘recent-jump)
这样,你就可以用C-o来重拾你中断的地方了,M-o绑定为向前跳跃。这样解释可能不太容易理解,试试就知道了,很好用的。
在Perl脚本中,允许调用系统的命令来进行操作。这就是Perl灵活性的体现,作为一种系统命令的粘合语言,能给程序员带来许多的便利。这样,你就可以最大限度地利用别人的成果,用不着自己使劲造轮子了。
在Perl中,可以用system、exec、readpipe这三个命令来调用其他脚本、系统命令等。这三个命令的主要区别就是返回值。
1) 对于system这个函数来说,它会返回执行后的状态,比如说
@args = (“command”, “arg1″, “arg2″);
system(@args) == 0
or die “system @args failed: $?”
当然,你也可以用类似于下面的语句来检查出错的原因:
if ($? == -1) {
print “failed to execute: $!\n”;
}
elsif ($? & 127) {
printf “child died with signal %d, %s coredump\n”,
($? & 127), ($? & 128) ? ‘with’ : ‘without’;
}
else {
printf “child exited with value %d\n”, $? >> 8;
}
2) 而对于exec这个函数来说,仅仅是执行一个系统的命令,一般情况下并没有返回值。exec只有在系统没有你要执行的命令的情况下,才会返回false值。
exec (‘foo’) or print STDERR “couldn’t exec foo: $!”;
{ exec (‘foo’) }; print STDERR “couldn’t exec foo: $!”;
3) 当我们需要保存系统命令运行的结果,以便分析并作进一步的处理时,就要用到readpipe这个函数了。例如:
@result = readpipe( “ls -l /tmp” );
print “@result”;
会产生如下的结果:
drwxr-xr-x 2 root root 4096 Mar 19 11:55 testdir
当然,你也可以把生成的结果放到一个文件里,以便写工作日志呀、发布报告呀。
$inject_command = “./ConfigChecker.bat F:/nic/3502/ARRAY-4AD2E0573/etc “.$device_name;
chdir “F:/TestTools/bin/”;
@temp_result = readpipe($inject_command);
open(result_file,”>result.txt”);
print result_file @temp_result;
close(result_file);
这样,你就把系统运行的结果扔到了系统命令所在目录下的result.txt文件里了。
这三个命令,有各自的特点,需要在使用时灵活选用,更详细的资料就得上PerlDoc上找了。
把下面的代码扔到.emacs里,就能实现相应的功能。
1) 把缺省的major mode设置为text-mode, 而不是几乎什么功能也没有的fundamental-mode.
(setq default-major-mode ‘text-mode)
2) 光标靠近鼠标指针时,让鼠标指针自动让开,别挡住视线。
(mouse-avoidance-mode ‘animate)
3) 防止页面滚动时跳动, scroll-margin 3可以在靠近屏幕边沿3行时就开始滚动,可以很好的看到上下文。这样就和我们一般的习惯一样了,不会半屏半屏的前后跳了。
(setq scroll-margin 3
scroll-conservatively 10000)
Emacs默认在标题栏显示emacs@computername这样的字符串,很没有意义,如下图所示:

我们可以通过修改.emacs来显示当前buffer的名字,只要把下面的代码加入到.emacs里即可:
(setq frame-title-format “emacs@%b”)
现在,Emacs的标题栏就显示为emacs@work.og,其中work.org就是当前buffer的文件名。

在《有关elisp括号配对的Emacs Mode》里,告诉了大家Emacs提供的show-paren-mode。这个mode应该能满足大家日常coding的需要了,不过,这个mode有一个缺点,就是,当你的光标在()中间的时候,两边的括弧不会有高亮显示。
在coding的时候,不能快速准确地找到离当前光标最近的()对,是件让人很辛苦的事。
现在再给大家介绍一个highlight-parentheses mode,这个mode能识别出离光标最近的那对parentheses。这些parentheses可以是()、[]、{}、《》中的任意一种。只要你把光标停留在一对parentheses中,这对parentheses就会自动高亮显示。
只要把highlight-parentheses.el扔到你的path里去,然后在.emacs里加入这段代码:
(add-to-list ‘load-path “/path/to/highlight-parentheses”)
(require ‘highlight-parentheses)
(highlight-parentheses-mode 1)
这样你就可以让highlight-parentheses-mode随着你的Emacs开启而激活了。当然,你也可以用命令M-x highlight-parentheses-mode来手动开启与关闭highlight-parentheses mode。
这样,一切有关parentheses高亮的东西,是不是完美了?
在写elisp的时候,要靠肉眼找到匹配的括号还真不容易。不过,Emacs提供了show-paren-mode可以实现这一功能。
我们可以用M-x show-paren-mode这个命令来启动这个mode。当然,你也可以在.emacs中进行类似于下面的设置来自动实现这个功能:
;; enable ShowParenMode
(setq show-paren-delay 0)
;(setq show-paren-style ‘parenthesis)
;(setq show-paren-style ‘expression)
(setq show-paren-style ‘mixed)
(show-paren-mode t)
其中,变量show-paren-delay用来设置延迟显示括号配对高亮的时间,以秒为单位。
变量show-paren-style则用来设置高亮显示的风格,有三种模式的参数:
1. parenthesis:只是高亮显示匹配的括号;
2. expression:把匹配括号里的表达式高亮显示;
3. mixed:如果配对的括号在当前屏幕中可见,则高亮显示这对括号;如果有一个括号不可见,则把所有的表达式高亮显示出来。
show-paren-delay和show-paren-style的设置都应该在show-paren-mode生效之前:
(show-paren-mode t)
当然,这个mode不仅能对括号配对,还可以对诸如{}、[]、《》这些成对的符号进行配对,使用十分方便。
今天看到《让拷贝和粘贴变得充满乐趣》这篇文章,觉得蛮有意思的。通过这样的编码,实现了对一行、一段、一个单词的自动化拷贝,在很多时候,的确是能减轻大家编码的工作量。
要做的其实非常简单,只要把以下代码放到.emacs里即可实现拷贝的自动化。
(defun copy-line (&optional arg)
“Save current line into Kill-Ring without mark the line”
(interactive “P”)
(let ((beg (line-beginning-position))
(end (line-end-position arg)))
(copy-region-as-kill beg end))
)(defun copy-word (&optional arg)
“Copy words at point”
(interactive “P”)
(let ((beg (progn (if (looking-back “[a-zA-Z0-9]” 1) (backward-word 1)) (point)))
(end (progn (forward-word arg) (point))))
(copy-region-as-kill beg end))
)(defun copy-paragraph (&optional arg)
“Copy paragraphes at point”
(interactive “P”)
(let ((beg (progn (backward-paragraph 1) (point)))
(end (progn (forward-paragraph arg) (point))))
(copy-region-as-kill beg end))
)
同样,根据这样的原理,我们还可以写出更多的、具有特殊功能的自动拷贝代码。