Perl

You are currently browsing articles tagged Perl.

YJubuntu: 批量处理照片的问题里介绍了他找到的在Ubuntu下批量处理照片的方法。他讲的两种方法都是基于GUI的。我到不是反对GUI,不过就像Andrew Tanenbaum (大牛阿,MINIX的作者,一堆经典CS教材的作者)的在他的FAQ (推荐读一下,挺有意思) 里说到的一条:

Do you like WYSIWYG systems?
Definitely not. I can type faster than I can point. And my mother told me that pointing is impolite.

没错,type faster than point,所以很多时候CLI会比GUI更高效便捷一点。我这一贴就说说我发现或找到的用CLI批量处理图片的方法。

这里都假设使用ImageMagick里的工具,YJ说的那个用Nautilus Image Scripts,最终调用的还是ImageMagick,相当一部分Linux(甚至Win下)的图像相关的自由软件都选择了调用ImageMagick提供的命令。

好了,假设在CLI下,resize一张照片A.JPG,用convert

  1. convert -resize 60% -quality 80 A.JPG A-resize.JPG

现在用同样的命令来批量处理同一个目录(及其子目录)下的所有JPG结尾的照片,我在Bash下用的命令是这样的:

  1. find . -name \*.JPG -print | awk -F.JPG '{ output = $1"-resize.JPG" ; cmd = "convert -resize 60% -quality 80 "$0" "output; system(cmd)}'

要是你嫌这条命令太过于安静,而你要同时处理很多照片,希望屏幕上能报告一下执行情况,可以这样:

  1. find . -name \*.JPG -print | awk -F.JPG '{ output = $1"-resize.JPG" ; cmd = "convert -resize 60% -quality 80 "$0" "output; print cmd; system(cmd)}'

这样之后,resize的照片是在当前目录下的,但是都重名了。Linux CLI下千变万化,同一件事情可能有无数种作法,比如我随便google了一下,就找到一篇,列一下里面提到的方法。

假设你在当前目录下,新建了一个目录/tmp/output,用来放resize后的照片,并且,你可以这样做:

  1. mkdir /tmp/output
  2. find . -name \*.JPG -exec convert -resize 60% -quality 80 {} /tmp/output/{} \;

用这个方法,你的output目录不能建在当前目录下(试试看,就知道为什么了), 而且没办法向上面那样重命名文件。用find的-exec还会有其他问题。find配合xargs会更有效率,比如

  1. find . -name "*.JPG" | xargs -l -i convert -resize 60% -quality 80 {} /tmp/output/{}

当然了,还可以使用perl强大的-e功能了,基本上是为所欲为了:

  1. mkdir output
  2. find . -iname "*.JPG" | perl -e 'for(<>) { chomp $_;@a=split ( /\// , $_ ) ;$str = "convert -resize 60% -quality 80 $_ output/".$a[-1];print $str."\n";`$str`}'

也可以调用shell的loop功能来通过循环做这件事情,比如在bash里可以

  1. for file in `find . -name \*.JPG`; do convert -resize 60% -quality 80 ${file} ${file%.*}-resize.JPG; done

总之,CLI下利用UNIX/LINUX的命令组合,常常会有非常简洁的实现,我上面提到的方法可能是很笨的,欢迎指正,补充。

如果要实现较为复杂的功能, 可以自己写Shell脚本,或者perl脚本等等。网上也有很多写好现成的,能实现各种功能,比如BBIPS: Bash Batch Image Processing Script,也是在CLI下用,看看它的screenshot

Related posts

Tags: , , , , , ,

手机的plan换到了verizon wireless。Verizon没有rollover,所以有时侯分钟数可能会紧张,如果打爆了,就会被罚不少钱。

在网上溜达的时候,看到在quiet earth发布了一个Verizon Wireless minute usage perl script。这个perl写成的script能够自动的登陆进你的verizion wireless的帐户,然后通过HTML Parser获取你这个billing cycle的分钟数的使用情况。作者的计划,是让这个script自动的将这个信息通过短信发往你的手机。不过,可以下载的那个脚本,还没有实现短信这一部分。

我觉得这个脚本的功能对我很有用,于是就拿了过来,做了一些修改,也发布在我这个blog。主要是加了短信那一部分。因为原作者发布的时候,没有任何license的信息,这种情况下我也不知道该按照何种license来发布,所以也就索性没有license了,反正一个小程序,弄着玩玩。如果原作者反对了,我就拿掉。

我修改过的脚本在这里下载。下载后请改名为verizionusage.pl。正如前面说得,主要的idea和code都来自于原来那个脚本,所以我本人没有什么太大贡献啦。

这个perl脚本使供在linux/unix下使用的,如果你想在windows下使用,需要做一些修改。

脚本下载后,需要修改开头的Configuration Section来填入一些你的手机的信息, 有详细的注释。基本上,你需要提供你在verizion wireless网站的帐号用户名和密码,你的10位数的手机号码 (写成xxxxxxxxxx,不要写成xxx-xxx-xxxx),你的email,你的plan的peak time的分钟数,和你希望报警的threshold。比如我的plan每个月是450分钟,我设置的threshold是400分钟。当我运行脚本,它如果发现当前的使用掉的分钟数已经超过了400分钟,脚本就会往我的手机送一条短信。送短信的机制很简单 (quite earth上提到了),verizon提供了一个vtext的服务,假设你的电话号码是3022345678,如果你发一封email到3022...@vtext.com,一条短信就会把这封email的内容送到该手机。另外,你还需要提供你系统里面sendmail的位置。我用的ubuntu,sendmail在/usr/sbin/sendmail (这里假设你的sendmail是配置好,可以用的)。

假设你把脚本拷贝到/usr/local/bin,然后你就可以将它加入linux的cron中,让系统来自动得定时运行它。 比如我写的是:

   0   22  *   *   *    /usr/local/bin/verizonusage.pl

这样,每天晚上10点的时候,这个脚本就会被系统自动执行。如果,当时的使用分钟数超过了你定义的threshold,一条短信就会被发送到手机。如果没有超过的话,就不会发送短信,这样就避免了过多发送短信(短信要钱的…)。你也可以自己时不时手工运行脚本来了解分钟数的使用情况。

如果verizon的网站改版了,这个脚本可能就不能使用了。据原作者说有25%的可能性被reject connection,所以如果在peak time打了很长的电话,最好手工运行一下脚本查一查,以防自动运行的那次正好没连上。


Related posts

Tags: , , ,