2013-07-18 137 views
1

我试图在文本文件中匹配文件路径并将它们替换为它们的共享文件路径。例如。字符串"X:\Group_14\Project_Security"我想替换为"\\Project_Security$"Perl字符串替换文本文件中的文件路径

由于我使用反斜杠(\)来转义另一个反斜杠(\\),但这似乎不适用于匹配文本文件中的路径,所以我在解决语法问题时遇到了问题。

open INPUT, '< C:\searchfile.txt'; 
open OUTPUT, '> C:\logsearchfiletest.txt'; 
@lines = <INPUT>; 
%replacements = (
    "X:\\Group_14\\Project_Security" => "\\\\Project_Security\$", 
    ... 
    (More Paths as above) 
    ... 
); 
$pattern = join '|', keys %replacements; 
for (@lines) { 
    s/($pattern)/@{[$replacements{$1}]}/g; 
    print OUTPUT; 
} 

不能完全确定发生了什么为"\\\\Project_Security\$"显示为\\Project_Security$"正确。

所以我觉得问题在于"X:\\Group_14\\Project_Security"没有评估到
"X:\Group_14\Project_Security"正确因此不能在文本文件中匹配吗?

任何意见,将不胜感激,干杯。

回答

1

如果所有的文件路径和替换是在一个类似的格式你的榜样,你应该能够做到以下几点,而不是使用哈希查找替换:

for my $line (@lines) { 
    $line =~ s/.+\\(.+)$/\\\\$1\$/; 
    print OUTPUT $line; 
} 
+0

使用散列的原因是他希望每行对600行搜索字符串和替换进行单次传递,而不必为150,000行中的每一行运行600次正则表达式引擎。查看我刚刚发布的原始问题的链接。 –

+0

我正在通过他的实际问题,而不是发布的代码。他暗示他想要替换这样的路径:“X:\ Group_14 \ Project_Security”,其股份如下:“\\ Project_Security $”“。在这种情况下,我发布的正则表达式会更加高效和可扩展。 – Muttley

1

一些注意事项:

  • 始终使用3个参数的开放
  • 经常访问打开,打印,或接近
  • 错误有时更容易使用,循环比CLEV呃编码

尝试:

#!/usr/bin/env perl 

use strict; 
use warnings; 

# -------------------------------------- 

use charnames qw(:full :short ); 
use English qw(-no_match_vars); # Avoids regex performance penalty 

use Data::Dumper; 

# Make Data::Dumper pretty 
$Data::Dumper::Sortkeys = 1; 
$Data::Dumper::Indent = 1; 

# Set maximum depth for Data::Dumper, zero means unlimited 
local $Data::Dumper::Maxdepth = 0; 

# conditional compile DEBUGging statements 
# See http://lookatperl.blogspot.ca/2013/07/a-look-at-conditional-compiling-of.html 
use constant DEBUG => $ENV{DEBUG}; 

# -------------------------------------- 

# place file names in variables to they are easily changed 
my $search_file  = 'C:\\searchfile.txt'; 
my $log_search_file = 'C:\\logsearchfiletest.txt'; 

my %replacements = (
    "X:\\Group_14\\Project_Security" => "\\\\Project_Security\$", 
    # etc 
); 

# use the 3-argument open as a security precaution 
open my $search_fh,  '<', $search_file  or die "could not open $search_file: $OS_ERROR\n"; 
open my $log_search_fh, '>', $log_search_file or die "could not open $log_search_file: $OS_ERROR\n"; 

while(my $line = <$search_fh>){ 

    # scan for replacements 
    while(my ($pattern, $replacement) = each %replacements){ 
    $line =~ s/\Q$pattern\E/$replacement/g; 
    } 

    print {$log_search_fh} $line or die "could not print to $log_search_file: $OS_ERROR\n"; 
} 

# always close the file handles and always check for errors 
close $search_fh  or die "could not close $search_file: $OS_ERROR\n"; 
close $log_search_fh or die "could not close $log_search_file: $OS_ERROR\n"; 
+0

关于三个参数选项,请纠正我,如果我错了,但我的印象是,在方向运算符和路径之间放置空间解决了路径的开始可能被解释为部分的可能性的问题的运营商。是否还有其他问题需要通过分隔空间来解决? –

0

我看到你贴我的生锈的Perl代码在这里,多么尴尬。 ;)我今天早些时候做了一个更新,在原来的PowerShell线程中给出了我的回答,它提供了一个更一般的解决方案,它也处理正则表达式元字符,并且不需要您手动转义600个散列元素中的每一个:PowerShell multiple string replacement efficiency。我将perlregex标记添加到您的原始问题中,但我的修改尚未获得批准。因为我最近一直在使用PowerShell来处理所有事情(这些天,我用PowerShell准备早餐...),我的Perl已经变得满是灰尘,我看到的还没有在这里未被注意到。 :P我固定了几个我注意到的东西可以更好地编码,当我第二次看时,这些东西在底部注明。我不打扰错误消息,声明和其他冗长的限制使用这种快速和肮脏的脚本,我不特别推荐它。正如Perl的座右铭所说的,“让简单易行的事情成为可能”。那么,这是一个让事情变得简单的例子,Perl的主要优点之一是,当你试图快速简单地做某件事情时,它不会强迫你“适当”。但我确实关闭了文件句柄。 ;)

相关问题