Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

multiline inplace edit

by meonkeys (Chaplain)
on Aug 07, 2003 at 01:09 UTC ( #281668=sourcecode: print w/replies, xml ) Need Help??
Category: Text Processing
Author/Contact Info Adam Monsen <adamm@wazamatta.com>
Description: Edit files in-place using a single regex (regular expression) that will be applied to the entire file as a string. Useful for applying multiline regexes and avoiding shell redirection and backup files. Also, quite dangerous!

Call like so:  ./edit.pl <regex> <files>...

example:

./edit.pl 's/your([\n\s]*?)friend/joe${1}${2}/ms' foo.txt

Please let me know if there is are easier/more elegant ways to do this, especially as a one-liner. When making suggestions, please keep in mind that my goals were to provide:

  • complete power of search and replace with Perl regexes
  • in-place file editing on multiple files
This script is mainly for Perl-savvy users or those familiar with Perl-compatible regular expressions.
#!/usr/bin/perl -w
use strict;                                                           
+           
use Getopt::Declare;

# $Id: multiline_inplace_edit.pl,v 1.5 2003/08/07 00:44:02 adamm Exp $

our $VERSION = 0.01;

our $usage_spec = <<'UsageSpec';
  [strict]

  Edit files in-place using a single regex that will be applied to
  the entire file as a string.

  <regex>               regex to be applied to files
                          [required]
  <files>...            one or more files to slurp in and run regex ag
+ainst
                          [required]

  WARNING: the first argument is added to an eval block!

  Example:
    ./edit.pl 's/your([\n\s]*?)friend/joe${1}${2}/ms' foo.txt
UsageSpec

our $args = new Getopt::Declare ($usage_spec) or die;

local $/;

for (@{$args->{'<files>'}}) {
  open (FH, "< $_") or die "error opening $_ for reading: $!";
  my $whole_file = <FH>;
  my $matching_code = '{ $whole_file =~ ' . $args->{'<regex>'} . ' }';
  eval $matching_code;
  die $@ if $@;
  close(FH) or die "error closing $!";

  open (FH, "> $_") or die "error opening $_ for writing: $!";
  print FH $whole_file;
  close(FH) or warn "error closing $!";
}
Replies are listed 'Best First'.
•Re: multiline inplace edit
by merlyn (Sage) on Aug 07, 2003 at 01:12 UTC
      How about -0777 instead of that clumsy BEGIN? ;) See perldoc perlrun. *tongue in cheek*

      Makeshifts last the longest.

      Damn. I knew it.

      Well, hope someone enjoys reading it, anyway! :)

      ---
      "A Jedi uses the Force for knowledge and defense, never for attack."

Re: multiline inplace edit
by Anonymous Monk on Aug 07, 2003 at 07:32 UTC

    I usually do this and I get the same result without a script.

    perl -i -0pe 's/foo/bar/g' file1 file2

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: sourcecode [id://281668]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others rifling through the Monastery: (9)
As of 2020-11-30 12:20 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?