2013-10-19 121 views
1

我想解決以下問題。如何使用Perl腳本動態地替換字符串

我有2個文件。 Address.txt和File.txt。我想用perl腳本將所有A/B/C/D(File.txt)替換爲相應的字符串值(從Address.txt文件讀取)。它不會替換我的輸出文件。我得到了相同的File.txt內容。 我嘗試了下面的代碼。

這裏是文件address.txt

A,APPLE 
B,BAL 
C,CAT 
D,DOG 
E,ELEPHANT 
F,FROG 
G,GOD 
H,HORCE 

下面是FILE.TXT

A B C 
X Y X 
M N O 
D E F 
F G H 

這裏是我的代碼:

use strict; 
use warnings; 
open (MYFILE, 'Address.txt'); 

foreach (<MYFILE>){ 
    chomp; 
    my @data_new = split/,/sm; 
    open INPUTFILE, "<", $ARGV[0] or die $!; 
    open OUT, '>ariout.txt' or die $!; 
     my $src = $data_new[0]; 
    my $des = $data_new[1]; 

     while (<INPUTFILE>) { 
      # print "In while :$src \t$des\n"; 
      $_ =~ s/$src/$des/g; 
      print OUT $_; 
     } 

     close INPUTFILE; 
     close OUT; 
     # /usr/bin/perl -p -i -e "s/A/APPLE/g" ARGV[0]; 
} 
close (MYFILE); 

如果我寫$ _ = 382 4/A /蘋果/克;

然後輸出文件很好,A用「Apple」替換。但是,當動態來臨時,它不會被取代。

在此先感謝。我是perl腳本語言的新成員。糾正我,如果我哪裏錯了。

更新1:我更新了下面的代碼。現在工作正常。我的問題這個算法的大O。 代碼:

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

open(my $out_fh, ">", "output.txt") || die "Can't open the output file for writing: $!"; 

open(my $address_fh, "<", "Address.txt") || die "Can't open the address file: $!"; 
my %lookup = map { chomp; split(/,/, $_, 2) } <$address_fh>; 

open(my $file_fh, "<", "File1.txt") || die "Can't open the file.txt file: $!"; 
while (<$file_fh>) { 
    my @line = split; 
    for my $char (@line) { 
     (exists $lookup{$char}) ? print $out_fh " $lookup{$char} " : print $out_fh " $char "; 
    } 
    print $out_fh "\n"; 
} 
+0

你沒有描述你面臨的問題 – Zaid

+0

編輯的問題..我沒有得到替換字符串。 –

回答

4

循環不完全確定你希望你的輸出格式化。你想保持行和列的原樣嗎?

我也採取了類似的做法同上,但保留了格式化一樣在你的「file.txt的」文件:

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

open(my $out_fh, ">", "output.txt") || die "Can't open the output file for writing: $!"; 

open(my $address_fh, "<", "address.txt") || die "Can't open the address file: $!"; 
my %lookup = map { chomp; split(/,/, $_, 2) } <$address_fh>; 

open(my $file_fh, "<", "file.txt") || die "Can't open the file.txt file: $!"; 
while (<$file_fh>) { 
    my @line = split; 
    for my $char (@line) { 
     (exists $lookup{$char}) ? print $out_fh " $lookup{$char} " : print $out_fh " $char "; 
    } 
    print $out_fh "\n"; 
} 

這會給你的輸出:

APPLE BAL CAT 
X Y X 
M N O 
DOG ELEPHANT FROG 
FROG GOD HORCE 
+0

你的代碼看起來非常好。但我沒有得到正確的格式輸出作爲我的輸入文件。輸出文件中有一些額外的空間。 –

+0

好吧,我做錯了 –

1

首先,這裏是你的現有程序,改寫略有

打開地址文件

地址文件轉換爲散列,這樣的字母鍵和字符串值

打開其他文件

在單行讀取它

行拆分成單字母

使用字母中的散列

use strict; 
use warnings; 

open(my $a,"Address.txt")||die $!; 

my %address=map {split(/,/) } map {split(' ')} <$a>; 

open(my $f,"File.txt")||die $!; 

my $list=<$f>; 

for my $letter (split(' ',$list)) { 
    print $address{$letter}."\n" if (exists $address{$letter}); 
} 

查找,使與地方的換人另一個文件改變這種處理$list

for my $letter (split(' ',$list)) { 
    if (exists $address{$letter}) { 
     push @output, $address{$letter}; 
    } 
    else { 
     push @output, $letter; 
    } 
} 

open(my $o,">newFile.txt")||die $!; 
print $o "@output"; 
+0

它只是替換第一行的單詞。 –

+0

你的代碼正在工作,但我的格式正在輸出文件中變得混亂.Extra空間在替換後出現。任何想法? –

1

你的問題在foreach循環的每次迭代中,都會覆蓋之前對輸出文件所做的任何更改。

我的解決辦法:

use strict; 
use warnings; 

open my $replacements, 'Address.txt' or die $!; 

my %r; 
foreach (<$replacements>) { 
     chomp; 
     my ($k, $v) = split/,/sm; 
     $r{$k} = $v; 
} 
my $re = '(' . join('|', keys %r) . ')'; 

open my $input, "<", $ARGV[0] or die $!; 

while (<$input>) { 
     s/$re/$r{$1}/g; 
     print; 
} 
2

這裏的另一種選擇,讓Perl來處理文件的打開和關閉:

use strict; 
use warnings; 

my $addresses_txt = pop; 
my %hash = map { $1 => $2 if /(.+?),(.+)/ } <>; 
push @ARGV, $addresses_txt; 

while (<>) { 
    my @array; 
    push @array, $hash{$_} // $_ for split; 
    print "@array\n"; 
} 

用法:perl File.txt Addresses.txt [>outFile.txt]

最後,可選參數指示輸出一份文件。

輸出你的數據集:

APPLE BAL CAT 
X Y X 
M N O 
DOG ELEPHANT FROG 
FROG GOD HORCE 

地址文件的名稱是隱含@ARGV使用的pop PED關閉後。然後,使用File.txt中的鍵/值對構建散列。

的地址文件被讀取,split婷各行成其單一的元件,並且所定義的 - 或(//)運算符用於返回所定義的散列項目或單獨的元件,其然後push編到@array 。最後,數組插入print語句中。

希望這會有所幫助!

0
#!/usr/bin/perl -w 
# to replace multiple text strings in a file with text from another file 

#select text from 1st file, replace in 2nd file 
$file1 = 'Address.txt'; $file2 = 'File.txt'; 

# save the strings by which to replace 
%replacement =(); 
open IN,"$file1" or die "cant open $file1\n"; 
while(<IN>) 
    {chomp $_; 
    @a = split ',',$_; 
    $replacement{$a[0]} = $a[1];} 
close IN; 

open OUT,">replaced_file"; 
open REPL,"$file2" or die "cant open $file2\n"; 
while(<REPL>) 
    {chomp $_; 
    @a = split ' ',$_; @replaced_data =(); 
# replace strings wherever possible 
    foreach $i(@a) 
     {if(exists $replacement{$i}) {push @replaced_data,$replacement{$i};} 
     else {push @replaced_data,$i;} 
     } 
    print OUT trim(join " ",@replaced_data),"\n"; 
    } 
close REPL; close OUT; 

######################################## 
sub trim 
{ 
my $str = $_[0]; 
$str=~s/^\s*(.*)/$1/; 
$str=~s/\s*$//; 
return $str; 
} 
相關問題