2009年10月19日星期一

[PerlChina] Re: 各位老大,继续是菜鸟问问题..麻烦了.

修改之前的文件会copy到*.bak备份~~~该方法得手动删除*.bak

On 10月18日, 下午2时34分, bio_gzd <tmfc...@gmail.com> wrote:
> perl还可以更简单
> perl -p -i.bak -w -e 's/some expr/rpl expr/g' filelist
>
> On 10月18日, 下午2时13分, Beckheng Lam <bi.ken....@gmail.com> wrote:
>
> > 比较详细,谢谢!
>
> > 钟声 wrote:
> > > 我找了段perl入门里的一段代码。。感觉这个更简单
>
> > > 9.5.3 更新大量文件
> > > 更新文件最常用的方法是写一个和以前的文件相似的新文件,我们可以根据的需
> > > 要进行修改。如你所知,这和对同一个文
> > > 件上进行更新的结果类似,但上述方法有一些副作用。
> > > 本例中,我们有相似格式的上百个文件。其中一个是fred03.dat,如下:
> > > Promram name: granite
> > > Author: Gilbert Bates
> > > Company: RockSoft
> > > Department: R&D
> > > Phone: +1 503 555-0095
> > > Date: Tues March 9, 2004
> > > Version: 2.1
> > > Size: 21k
> > > Status: Final beta
> > > 我们希望修改这个文件,使之含有不同的信息。下面是我们希望修改后它所呈现
> > > 的样式:
> > > Program name: granite
> > > Author: Randal L. Schwartz
> > > Company: RockSoft
> > > Department: R&D
> > > Date: June 12, 2008 6:38 pm
> > > Version: 2.1
> > > Size: 21k
> > > Status: Final beta
> > > 简言之,我们需要在3 个地方进行修改。作者(Author)的名字需要更改,日期
> > > (Date)需要更新,电话(Phone)需要删除。
> > > 我们需要在上百个这样的文件中作这些修改。
> > > Perl 可以通过尖括号操作符(<>)对文件进行修改。下面程序能完成我们希望的
> > > 工作,虽然第一次看时,不是很明显。这个
> > > Perl 语言入门(第四版)
> > > b...@163.com <mailto:b...@163.com> 118 / 201 9/21/2006
> > > 程序只有一个新的特性:特殊变量$^I;现在可以不用管它,我们将在后面讨论:
> > > #! /usr/bin/perl -w
> > > use strict;
> > > chomp(my $date = 'date');
> > > $^I =".bak";
> > > while(<>){
> > > s/^Author:.*/Author: Randal L. Scharwartz/;
> > > s/^Phone:.*\n//;
> > > s/^Date:.*/Date: $date/;
> > > print;
> > > }
> > > 由于需要当前的日期,因此在程序开端使用了系统命令:date。另一种获得时间
> > > 的更好的方法是(格式有些不同)使用Perl
> > > 自带的localtime 函数,其在标量context 中使用:
> > > my $date = localtime;
> > > 下一行是给$^I 赋值,我们现在不讨论它。
> > > 根据我们现在所知的,上述操作的结果是文件中新修改的部分被输出到终端,内
> > > 容快速滚动,但文件本身不会被修改。
> > > 由尖括号操作(<>)所得到的文件列表来源于命令行。主循环读入,更新,输出
> > > 每一行。(根据我们现在所知的,上述操作
> > > 的结果是文件中被修改的部分被输出到终端,这些内容快速滚动,但文件本身不
> > > 会被修改。)第二个替换操作将含有电话
> > > (phone)号码的整行由空串替换,连换行符一起替换掉。这行输出时,什么也不
> > > 会出现,就像电话(Phone)号码从没存在过一
> > > 样。还有大量的行不会被这三个模式所匹配,他们在输出时不会有任何更改。
> > > 结果接近于我们所期望的了,除了还不知道怎样将更新的信息写回文件。答案是
> > > 变量$^I。默认时为undef,此时没有什么
> > > 特殊的地方。但给它设置某些串时,它使尖括号操作(<>)变得有些特殊。
> > > 我们知道尖括号(<>)的神奇特点:如果没有指定文件名,则其从标准输入流中自
> > > 动打开和关闭一系列文件进行读入。但如
> > > 果$^I 中有字符串,这个字符串则会成为备份文件的扩展名。我们在下面仔细讨论。
> > > 我们假设此时尖括号(<>)打开的文件是fred03.dat。它像以前那样打开它,但进
> > > 行了重名名,把它叫做 fred03.dat.bak◆。这
> > > 很好,因为不在使用之前的名字。现在<>将这个新的文件作为默认的输出,因此
> > > 任何内容将输出到那个文件中◆。while
> > > 循环会从旧的文件中读入一行,更新它,再把它输出到新文件中。在一台普通的
> > > 机器上运行这个程序,几秒钟就能更新上
> > > 百个文件。非常强大,不是吗?
>
> > > 2009/10/18 Beckheng Lam <bi.ken....@gmail.com
> > > <mailto:bi.ken....@gmail.com>>
>
> > > Cool~~~ ;-)
>
> > > bio_gzd wrote:
> > > > OH YEAH.总算是搞定了.贴上代码.
> > > > chop $new_tid=<STDIN>;
> > > > my @FILE = undef;
> > > > open FH, $_tid_file or die "文件打开错误,请检查!!";
> > > > @FILE = <FH>;
> > > > close (FH);
> > > > open WRTIDFILE,'>', $_tid_file or die "文件打开错误,请检查!!";
> > > > foreach (@FILE) {
> > > > s/^(TerminalID)\=(\d{8})/$1=$new_tid/g ;
> > > > print WRTIDFILE ;
> > > > }
> > > > close (WRTIDFILE);
> > > > }
>
> > > > 用foreach来遍历一遍整个数组,之后直接写入句柄,关闭..就这样简单..
>
> > > > On 10月17日, 下午9时00分, bio_gzd <tmfc...@gmail.com
> > > <mailto:tmfc...@gmail.com>> wrote:
>
> > > >> 分开写..试了一下,不行.难道我写错了?有很大可能啊..
> > > >> my @FILE = open FH, $_tid_file or die "文件打开错误,请检查!!";
> > > >> close (FH);
> > > >> open WRTIDFILE,'>', $_tid_file or die "文件打开错误,请检查!!";
> > > >> while (@FILE) {
> > > >> s/^(TerminalID)\=(\d{8})/$1=$new_tid/g ;
> > > >> print WRTIDFILE ;
> > > >> }
> > > >> close (WRTIDFILE);
>
> > > >> On 10月17日, 上午11时27分, bio_gzd <tmfc...@gmail.com
> > > <mailto:tmfc...@gmail.com>> wrote:
>
> > > >>> 分开写?试过,但是之前的读没关闭,少了这一步.一会试试..
>
> > > >>> On 10月17日, 上午8时32分, silent <silent2...@gmail.com
> > > <mailto:silent2...@gmail.com>> wrote:
>
> > > >>>> 额... 你是想改写文件的内容, 那么一边读一边写一个文件句柄恐怕
> > > 不可以
> > > >>>> 用两个吧,
> > > >>>> 1种方法是先全读出来放倒变量里, 再关闭文件, 从新以写打开,在把
> > > 替换过的内容写进去
> > > >>>> 或者用林时候文件,最后在改名字覆盖
>
> > > >>>> 2009/10/17 silent <silent2...@gmail.com
> > > <mailto:silent2...@gmail.com>>:
>
> > > >>>>> while (<TIDFILE>) { 是表示读的意思
> > > >>>>> 写入的方法是 print TIDFILE $xxstring
>
> > > >>>>> 加油!
>
> > > >>>>> 2009/10/17 bio_gzd <tmfc...@gmail.com
> > > <mailto:tmfc...@gmail.com>>:
>
> > > >>>>>> 有以下程序段,各位看看有错误没?是一个用正则改写文件内容的
>
> > > >>>>>> unless ($new_tid =~ m/^\d{8,8}[^\w]/) {
> > > >>>>>> print "输入错误或为空行";
> > > >>>>>> } else {
> > > >>>>>> chop $new_tid;
> > > >>>>>> open TIDFILE, ">$_tid_file" or die "文件打开错误,请检查!!";
> > > >>>>>> while (<TIDFILE>) {
> > > >>>>>> s/^(TID)\=(\d{8})/$1=$new_tid/g ;
> > > >>>>>> print ;
> > > >>>>>> close (TIDFILE);
> > > >>>>>> }
>
> > > >>>>>> 看看有错没?总是无法写入,如果TIDFILE里面不设置重定向符,直接
> > > print输出结果证明替换是正确的,但是一旦要写入到TIDFILE里面要么
> > > >>>>>> 出错,要么就是0字节.问题出在哪里?麻烦各位指点一下了.
>
> > > <http://www.perlersh.org/blog.html>
>
> > --
> > Perl乐事 --http://www.perlersh.org
> > 我的博客 --http://www.perlersh.org/blog.html
--~--~---------~--~----~------------~-------~--~----~
您收到此信息是由于您订阅了 Google 论坛"PerlChina Mongers 讨论组"论坛。
要在此论坛发帖,请发电子邮件到 perlchina@googlegroups.com
要退订此论坛,请发邮件至 perlchina+unsubscribe@googlegroups.com
更多选项,请通过 http://groups.google.com/group/perlchina?hl=zh-CN 访问该论坛
-~----------~----~----~----~------~----~------~--~---

没有评论: