2013-07-18 175 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的主要優點之一是,當你試圖快速簡單地做某件事情時,它不會強迫你「適當」。但我確實關閉了文件句柄。 ;)

相關問題