open a file and replace a word using perl

perl

Solution

You can use a perl oneliner from a command line. No need to write a script.

perl -p -i -e "s/`timescale\s1ns/`timescale 1ps/g" pcie_7x_v1_7.v

However,

If you still want to use the script, you are almost there. You just need to fix a couple errors

print $line; #missing 

if ($line =~ /timescale\s1ns/) #made it a real regex, this should match now

$line =~ s/`timescale 1ns/`timescale 1ps/g ; #added g to match all occurences in line

after the `if-else` you must print the line to a file again

for example, open a new file for writing (let's call it 'pcie_7x_v1_7.v.2') at the beginning of your script

open(my $fh2, ">", "pcie_7x_v1_7.v.2" ) or die "cannot open <pcie_7x_v1_7.v.2:$!" ;

then , after the else block just print the line (whether it's changed or not) to the file

print $fh2 $line;

Don't forget to close the filehandles when you're done

close($fh);
close($fh2);

EDIT:

Your main problem was that you used `$_` for the check, while you had assigned the line to `$line`. So you did `print $line`, but then `if ($_ =~ /timescale/`. That would never work. I'm copy pasting your script and made a couple corrections and formatted it a little more dense to better fit in the website. I also removed the `if match` check as suggested by TLP and directly did the substitution in the if. It has exactly the same result. This works:

use strict;
use warnings;

open(my $fh, "<", "pcie_7x_v1_7.v" )
    or die "cannot open <pcie_7x_v1_7.v:$!" ;
open( my $fh2, ">", "pcie_7x_v1_7.v2")
    or die "cannot open >pcie_7x_v1_7.v2:$!" ;

while(my $line = <$fh> ) {
    print $line;
    if ($line =~ s|`timescale 1ns/1ps|`timescale 1ps/1ns|g) {
        print "pattern found and replaced\n ";
    }
    else {
        print "pattern not found \n ";
    }
    print $fh2 $line ;
}
close($fh);
close($fh2);

#now it's finished, just overwrite the old file with the new file
rename "pcie_7x_v1_7.v2", "pcie_7x_v1_7.v";

Problem

I want to open a file and replace a word from a file. My code is attached here. ``` open(my $fh, "<", "pcie_7x_v1_7.v") or die "cannot open <pcie_7x_v1_7.v:$!"; while (my $line = <$fh>) { if ($line =~ timescale 1 ns) { print $line $msg = "pattern found \n "; print "$msg"; $line =~ s/`timescale 1ns/`timescale 1ps/; } else { $msg = "pattern not found \n "; print "$msg"; } } ``` File contains pattern `timescale 1ns/1ps`. My requirement is to replace `timescale 1ns/1ps` to be replaced with `timescale 1ps/1ps`. At present else condition occurs always. Update code after receiving comment: Hi, Thanks for the quick solution. I changed the code accordingly, but the result was not successful. I have attached the updated code here. Please suggest me if I missed anything here. ``` use strict; use warnings; open(my $fh, "<", "pcie_7x_v1_7.v" ) or die "cannot open <pcie_7x_v1_7.v:$!" ; open( my $fh2, ">", "cie_7x_v1_7.v2") or die "cannot open <pcie_7x_v1_7.v2:$!" ; while(my $line = <$fh> ) { print $line ; if ($_ =~ /timescale\s1ns/ ) { $msg = "pattern found \n " ; print "$msg" ; $_ =~ s/`timescale 1ns/`timescale 1ps/g ; } else { $msg = "pattern not found \n " ; print "$msg" ; } print $fh2 $line ; } close($fh) ; close($fh2) ; ``` Result: pattern not found pattern not found pattern not found pattern not found Regards, Binu 3rd update: // File : pcie_7x_v1_7.v // Version : 1.7 // // Description: 7-series solution wrapper : Endpoint for PCI Express // //-------------------------------------------------------------------------------- ``` //`timescale 1ps/1ps `timescale 1ns/1ps (* CORE_GENERATION_INFO = "pcie_7x_v1_7,pcie_7x_v1_7, ```

Original source