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");