1

我正在尝试匹配文本文件中的文件路径并将它们替换为它们的共享文件路径。EG"X:\Group_14\Project_Security"我要替换的字符串"\\Project_Security$"

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

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"因此在文本文件中不匹配?

对此的任何建议将不胜感激,干杯。

4

3 回答 3

1

一些注意事项:

  • 始终使用 3 参数 open
  • 始终检查打开、打印或关闭时的错误
  • 有时循环比聪明的编码更容易使用

尝试:

#!/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";
于 2013-07-18T13:19:12.887 回答
1

如果所有文件路径和替换的格式与您的示例类似,您应该能够执行以下操作,而不是使用散列来查找替换:

for my $line (@lines) {
    $line =~ s/.+\\(.+)$/\\\\$1\$/;
    print OUTPUT $line;
}
于 2013-07-18T11:20:20.343 回答
0

我看到你在这里发布了我生锈的 Perl 代码,多么尴尬。;) 我今天早些时候对原始 PowerShell 线程中的答案进行了更新,它提供了一个更通用的解决方案,该解决方案还可以处理正则表达式元字符,并且不需要您手动转义 600 个哈希元素中的每一个:PowerShell 多字符串替换效率。我将perlregex标签添加到您的原始问题中,但我的编辑尚未获得批准。

[正如我所提到的,由于我最近一直在使用 PowerShell(哎呀,这些天我用 PowerShell 准备早餐......),我的 Perl 有点尘土飞扬,我看到这里并没有被忽视。:PI 修复了一些我注意到在我第二次查看时可以更好地编码的东西,这些都在底部注明。对于像这样的有限使用的快速和肮脏的脚本,我不会为错误消息和声明以及其他冗长而烦恼,我也不特别推荐它。正如 Perl 的座右铭所说,“让简单的事情变得简单,让困难的事情成为可能”。嗯,这是一个让简单的事情变得简单的例子,Perl 的主要优点之一是当您尝试快速简单地做某事时,它不会强迫您“正确”。但我确实关闭了文件句柄。;)

于 2013-07-20T01:59:35.287 回答