2015-03-13 3 views
0

Я написал код, но он не работает нормально. Я хочу изменить этот «/» на этот «\».Как обновить определенную часть текстового файла в perl

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 

ответ

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

0

Вам не нужно написать программу этого добиться это. Вы можете использовать Perl Pie:

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

Однако, если вы работаете на окнах, и вы используете Cygwin, я бы предложил использовать cygpath инструмент, который преобразует POSIX пути в путях 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; 
+6

Chosing различного характера предотвращает падающую зубочистку синдрома: 'ы =/= \\ = г;' – choroba

1

Если точка упражнения меньше об использовании регулярных выражений, и больше о том, чтобы все сделали, я бы рассмотреть возможность использования модулей из семейства 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"; 
} 
Смежные вопросы