【问题标题】:Copy a file to another while replacing variables in Perl?在 Perl 中替换变量时将文件复制到另一个文件?
【发布时间】:2018-11-13 17:38:45
【问题描述】:

我有一个问题我是 Perl 新手,但我找不到问题的答案。

我必须创建一个文件,将另一个文件的内容复制到这个新创建的文件中。但是复制的文件有一些变量$var1$var2,我必须用新文件中这些变量的内容(插值)替换它们。

我真的不知道如何同时创建、打开文件、复制和插值......

有什么想法吗?


这是我的代码:

sub my_function ($)
{
 My $var = shift ;
 open (FH, ‘>’, « file1 ») ; #this file is created because it doesn’t exist. 

 Copy($file_to_copy, $FH) ;
  while (my $line = <$FH>)
  {
    if ($line =~ /(Substituethis)/   
    {
      $line =~ s/$1/$var/g;
      print $FH $line;
    }
  }
  close $FH;
}

【问题讨论】:

  • 我们确实需要更多细节才能给出答案。像一些代码或示例数据,所需的输出。但我建议开始查找的地方是搜索和替换正则表达式、打开和读取文件以及使用搜索和替换哈希。
  • 我已经评估了我的代码,我希望它足够清楚!我有一个错误:未打开的文件句柄上的 readline.. 可能是因为我不能同时读写?
  • 我建议将您遇到的错误添加到您的问题中。
  • 样本输入和输出可能吗?

标签: perl file


【解决方案1】:

好的,首先关闭 - 打开 use strict;use warnings;。 您的代码中有几个语法错误。

特别是,FH - 您正在打开的 - 和您正在阅读的 $FH 不是一回事,即使它们是,......您不能同时从同一个文件读取/写入(至少,不是那样)。

另外 - Mymy 不同,所以它也会中断。

您可能不会那样声明 sub ——您是在进行原型设计,但这并不意味着您认为它的含义,因为 perl 原型与其他语言不同。

做你想做的 - 例如。替换一些 'placeholders' 看起来有点像这样:

#!/usr/bin/env perl
use strict;
use warnings;   

#define replacement patterns in a hash. (see 'perldoc hash')

my %replace = (
  '$var1' => "a word here",
  '$var2' => "another different word here", 
);

#compile a regular expression that looks for the placeholders.
#note - we need "quotemeta" here because your search patterns include $
my $search = join "|", map { quotemeta } keys %replace;
   $search = qr/($search)/;

print "Using regex for matching:",$search,"\n";


#iterate STDIN (or file specified on command line) line by line
while ( <> ) { 
   #apply pattern matches to current line
   s/$search/$replace{$1}/g; 
   #print current line
   print;
}

我们在上面使用&lt;&gt;,因为它是文件处理更简单的选项之一 - 这意味着您的脚本可以像sed/awkgrep 一样工作,因为您可以在命令行上指定文件名,或者只是将文件通过管道传输给它。

但是,如果您想打开-写入,您可以:

open ( my $input, '<', 'filename_here' ) or die $!;
open ( my $output, '>', 'output_filename' ) or die $!;

select $output; #set output source for print location
while ( <$input> ) {
   #apply pattern matches to current line
   s/$search/$replace{$1}/g; 
   #print current line
   print;
}   

这将逐行读取您的输入文件,并将(转换后的)输出写入新文件。

【讨论】:

  • 非常感谢!但我有最后一个问题。我有很多数据文件,我的变量 $var1 和 $var2 变化很大,我可以通过哈希来移动我的函数中的变量吗?
  • 是的,当然。你只需要看看如何你想要改变它们。 $replace{$1} 查找发生在运行时,因此您甚至可以随时动态更改它们。
  • 是的,很高兴它完美地工作!感谢您的帮助!
【解决方案2】:

这个解决方案对我来说很好用:

use strict;
use warnings;

sub myfunction () 
{
  open ( my $input, '<', ‘file_name’ ) or die $!;
  open ( my $output, '>', ‘output_file_name’ ) or die $!; 

  my $var1 = "cup";
  my $var2 = "tea";

  my  %replace = (
   '$var1' => "round" ;
   '$var2' => "sweet",
  );

  my $search = join "|", map { quotemeta } keys %replace;
  $search = qr/($search)/;

  print "Using regex for matching:",$search,"\n";

  while ( <$input> )
  {
    s/$search/$replace{$1}/g; 
    print;
  }    
}

【讨论】:

  • 您从不使用my $var1 = "cup";my $var2 = "tea";。也许您希望您的哈希 %replace 看起来像 '$var1' =&gt; $var1
  • 你应该去掉 myfunction() 后面的括号——这是一个原型,它们很复杂。 (而且可能不会做你想做的事)。
猜你喜欢
  • 2013-10-11
  • 2016-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-22
  • 2018-01-22
  • 1970-01-01
  • 2018-06-27
相关资源
最近更新 更多