Can't replace word in given contents of Sed / Python / Perl folder

I have a project in which I have folders, subfolders and files. I need to replace Masi with Bond in every file.

I am running the following Sed script which is called unsuccessful replacement

s/Masi/Bond/

      

in Zsh on

sed -f PATH/replace PATH2/project/**

      

It gives me all the files as well as the ones that don't have Masi as output.

Sed is not necessarily the best tool for the task. I'm interested in Python and Perl.

How do I perform a substitution in Sed / Perl / Python to only change the contents of a file?

0


a source to share


5 answers


To replace a word in all files found in the current directory and subdirectories

perl -p -i -e 's/Masi/Bond/g' $(grep -rl Masi *)

      

The above won't work if you have spaces in the filenames. Safer:

find . -type f -exec perl -p -i -e 's/Masi/Bond/g' {} \;

      



or on a Mac that has spaces in filenames

find . -type f -print0 | xargs -0 perl -p -i -e 's/Masi/Bond/g'

      

Clarifications

  • -p means seal or stamp
  • -i means "do not create backup files"
  • -e allows you to run perl code on the command line
+12


a source


Why not just pass the -i

( man sed

) parameter to sed and be done with it? If it doesn't find Masi in the file, the file will simply be overwritten without any changes. Or am I missing something?

If you don't want to replace the content of the inline file (which is what it will do -i

), you can do what you are now, but throw in front of it grep

andxargs

grep -rl Masi PATH/project/* | xargs sed -f PATH/replace

      



Lots of options, but don't write an entire perl script to do this (I'll give a one line pass;)). find

, grep

, sed

, xargs

, Etc. will always be more flexible, IMHO.

In response to a comment:

grep -rl Masi PATH/project/* | xargs sed -n -e '/Masi/ p'

      

+3


a source


Rename file folder:

use warnings;
use strict;
use File::Find::Rule;

my @list = File::Find::Rule->new()->name(qr/Masi/)->file->in('./');

for( @list ){
   my $old = $_;
   my $new = $_;
   $new =~ s/Masi/Bond/g;
   rename $old , $new ;
}

      

Replacing strings in files

use warnings;
use strict;
use File::Find::Rule;
use File::Slurp;
use File::Copy;

my @list = File::Find::Rule->new()->name("*.something")->file->grep(qr/Masi/)->in('./');

for( @list ){
   my $c = read_file( $_ );
   if ( $c =~ s/Masi/Bond/g; ){
    File::Copy::copy($_, "$_.bak"); # backup.
    write_file( $_ , $c );
   }
}

      

+3


a source


Solution tested on Windows

Requires CPAN Module File :: Slurp. Will work with standard Unix shell templates. How. /replace.pl PATH / replace.txt PATH2 / replace *

#!/usr/bin/perl

use strict;
use warnings;
use File::Glob ':glob';
use File::Slurp;
foreach my $dir (@ARGV) {
  my @filelist = bsd_glob($dir);
  foreach my $file (@filelist) {
    next if -d $file;
    my $c=read_file($file);
    if ($c=~s/Masi/Bond/g) {
      print "replaced in $file\n";
      write_file($file,$c);
    } else {
      print "no match in $file\n";
    }
  }
}

      

0


a source


import glob
import os

# Change the glob for different filename matching 
for filename in glob.glob("*"):
  dst=filename.replace("Masi","Bond")
  os.rename(filename, dst)

      

0


a source







All Articles