views:

152

answers:

4

Hello friends,

I have a file that contains:

foo1 = 1

foo2 =  2

foo3 =    8

.
.
.

I need to replace only the values (1,2,8...) in that file with part of a memory hash values, the ones with the same keys (foo1 -> 33,foo2 -> 44,foo3...) How can I change it using the "s///" operator? If there is other elegant ways to conduct it I'll be happy to know.

Thanks for any help,

Yohad.

+1  A: 

one way

%hash = ("foo1"=>33,"foo2" => 44,"foo3"=>99);
while (<>){
  chomp;
  ( $one , $two ) = split /\s+=\s+/, $_;
  print "$one = $hash{$one} \n"
}
ghostdog74
You might want to clarify that to actually save the new value, you need to do `$hash{$one} = $two;`
Telemachus
actually, i thought OP wants to update his file. That's why i use print instead so that OP can redirect to new file on the command line. (of course another way is to use open() with write ), anyway.....
ghostdog74
You're right. I got the OP's request backward. I thought he wanted to update a saved `%hash` based on the records in the file, but I now see that you're right about what he wants.
Telemachus
First of all, thank you for your answer, it's quite understandable! But my input file follow like this: foo1_____ =_______ 1 foo2__ =_ 2 it has unexpected spaces that disturb finding my hash key. so what shell I write in the split function in order to ignore to space characters ?
YoDar
edited to check for extra spaces...
ghostdog74
Thanks a lot.that was very helpful!
YoDar
A: 

s/regexPattern/replacementPattern/flags

"I am a string!"

s/\sam/'s/g

"I's a string!"

http://gnosis.cx/publish/programming/regular_expressions.html

I really can't understand what you're doing based on the descriptoin. Can you provide sample input and output?

Stefan Kendall
input file: [name][spaceeeeeee] = [spacee][number]output file: [name] = [$hash{name}]
YoDar
+2  A: 

Here's one

%h = ("foo1"=>3, "foo2"=>5);
while (<>)
{
    #Substitute value according to expression on right hand side
    s/(\w+) = .*/$1 . " = ". $h{$1}/e;
    print;
}
Hasturkun
+6  A: 
my %new_values = ( foo1 => 33, ... );
$data =~ s{^(?<key>\w+) = \K(?<old_value>.+)$}
          {$new_values{$+{key}}}gem;

The key is the "e" flag which lets you run code to determine the replacement. The (?<...>) syntax increases readability, and the \K allows us to match the entire line but only replace the value area. The "g" flag repeats the substitution as many times as possible, and the "m" flag makes ^...$ match a line instead of the entire string. (The g and m will probably be unnecessary if you split the lines before application of the regexp.)

jrockway
Why "{}" instead of "//"? And what's "+" in "$+{key}"? I found the example very interesting, but I found it difficult to read, and I know what you are doing. This answer could really benefit from an extensive revision for dummies. :-)
Daniel
@ Daniel: it's a named capture. `$+{key}` refers back to the item captured (and named) in `(?<key>\w+)`. See the named captures section here: http://perldoc.perl.org/perlre.html
Telemachus
@Jrockway: I'm not sure I would say anything about it has "increased readability", but +1 for giving me a reason to reread `perldoc perlre`. Very cool
Telemachus
Note that \K and (?<name>...) require 5.10 or higher.
ysth