Regex 如何在perl中更新文本文件的某些部分

Regex 如何在perl中更新文本文件的某些部分,regex,perl,Regex,Perl,我写的代码,但它不是很好。我想把这个“/”改成这个“\” 预期产量为 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 原始输出为 C:\etc\passwd C:\home\bob\bookmarks.xml C:\h

我写的代码,但它不是很好。我想把这个“/”改成这个“\”

预期产量为

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
原始输出为

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

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

perl -pi -e 's|/|\\|g; s|\\|c:\\|;' unix_url.txt
但是,如果您在windows上运行并且使用Cygwin,我建议您使用将POSIX路径转换为windows路径的
cygpath
工具

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

perl -pi -e 's|/|\\/g; s|\\|c:\\|; s| |\\ |g;' unix_url.txt
现在,关于您的初始问题,如果您仍然想要使用自己的脚本,您可以使用以下内容(如果您想要备份):

使用严格;
使用自动模具;
使用文件::复制;
my$file=“unix_url.txt”;
打开我的$fh,“,$file.bak”;
而(){
s/\/\\/g;
s/\\/c:/;
}继续{print$tmp$}
关闭$tmp;
收盘价$fh;
移动“$file.bak”,$file;

< /代码> 如果练习的点少了关于使用正则表达式,以及更多关于完成的事情,我会考虑使用来自家庭的模块:

使用警告;
严格使用;
使用File::Spec::Win32;
使用File::Spec::Unix;
while(my$unixpath=){
my@pieces=File::Spec::Unix->splitpath($unixpath);
我的$winpath=File::Spec::Win32->catfile('c:',@pieces);
打印“$winpath\n”;
}

试图一行一行地读写同一个文件,在一个while循环中一直读到同一个文件的末尾,这看起来非常危险和不可预测。我一点也不确定每次尝试编写时,您的文件指针将在哪里结束。将输出发送到新文件(如果愿意的话,随后将其移动以替换旧文件)会更安全

open(数据,“win_url.txt”)或die(“无法打开文件进行写入!”);
while(){
s/\/\\/g;
s/\\/c:\\/;
#^(注意-从预期输出中,您还希望保留此反斜杠)
打印新数据$;
}
关闭(数据);
关闭(新数据);
重命名(“win_url.txt”、“unix_url.txt”);
另见此答案:

选择一个不同的角色可以预防倾斜牙签综合症:
s=/=\\\=g
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;  
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";
}
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");