【问题标题】:How to update certain part of text file in perl如何在perl中更新文本文件的某些部分
【发布时间】:2015-03-14 21:28:20
【问题描述】:

我已经编写了代码,但它不能正常工作。我想把这个“/”改成这个“\”。

use strict;
use warnings;

open(DATA,"+<unix_url.txt") or die("could not open file!");

while(<DATA>){

s/\//\\/g;
s/\\/c:/;
print DATA $_;

}

close(DATA);

我的原始文件是

/etc/passwd 
/home/bob/bookmarks.xml 
/home/bob/vimrc

预期输出是

C:\etc\passwd
C:\home\bob\bookmarks.xml
C:\home\bob\vimrc 

原来的输出是

/etc/passwd
/home/bob/bookmarks.xml
/home/bob/vimrc/etc/passwd
\etc\passwd
kmarks.xml
kmarks.xml
mrcmrc

【问题讨论】:

    标签: regex perl


    【解决方案1】:

    尝试在一个一直读取到同一个文件末尾的while循环中逐行读取和写入同一个文件,这似乎非常冒险且不可预测。我完全不确定每次您尝试写入时您的文件指针将在哪里结束。将输出发送到新文件会更安全(如果您愿意,然后将其移动以替换旧文件)。

    open(DATA,"<unix_url.txt") or die("could not open file for reading!");
    open(NEWDATA, ">win_url.txt") or die ("could not open file for writing!");
    
    while(<DATA>){
        s/\//\\/g;
        s/\\/c:\\/;
        #       ^ (note - from your expected output you also wanted to preserve this backslash)
        print NEWDATA $_;
    }
    
    close(DATA);
    close(NEWDATA);
    rename("win_url.txt", "unix_url.txt");
    

    另请参阅此答案: Perl Read/Write File Handle - Unable to Overwrite

    【讨论】:

      【解决方案2】:

      如果练习的重点不是使用正则表达式,而是更多关于完成任务,我会考虑使用 File::Spec 系列中的模块:

      use warnings;
      use strict;
      use File::Spec::Win32;
      use File::Spec::Unix;
      while (my $unixpath = <>) {
        my @pieces = File::Spec::Unix->splitpath($unixpath);
        my $winpath = File::Spec::Win32->catfile('c:', @pieces);
        print "$winpath\n";
      }
      

      【讨论】:

        【解决方案3】:

        你真的不需要编写程序来实现这一点。你可以使用 Perl Pie:

        perl -pi -e 's|/|\\|g; s|\\|c:\\|;' unix_url.txt
        

        但是,如果您在 Windows 上运行并且使用 Cygwin,我建议使用 cygpath 工具将 POSIX 路径转换为 ​​Windows 路径。

        您还需要引用您的路径,因为它允许在 Windows 路径中包含空格。或者,您可以转义空格字符:

        perl -pi -e 's|/|\\/g; s|\\|c:\\|; s| |\\ |g;' unix_url.txt
        

        现在关于您最初的问题,如果您仍想使用自己的脚本,您可以使用这个(如果您想要备份):

        use strict;
        use autodie;
        use File::Copy;
        
        my $file = "unix_url.txt";
        open my $fh,  "<",  $file;
        open my $tmp, ">", "$file.bak";
        while (<$fh>) {
            s/\//\\/g;
            s/\\/c:/;
        } continue { print $tmp $_ }
        close $tmp;
        close $fh;
        move "$file.bak", $file;  
        

        【讨论】:

        • 选择不同的角色可以防止倾斜牙签综合症:s=/=\\=g;
        猜你喜欢
        • 2011-04-22
        • 2011-09-26
        • 2020-03-17
        • 2021-03-04
        • 1970-01-01
        • 2014-09-18
        • 2011-01-19
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多