| Chess | Tools | Data | Blog | Poetry | Why? | Wiki | Admin | Logout |

Download


#!/usr/bin/perl -w
# $Revision: 1.32 $
# Luis Mondesi < lemsx1@gmail.com >
#
# URL: http://www.kiskeyix.org/downloads/fgrep.pl.gz
#
# DESCRIPTION: finds a string in a set of files
#
# USAGE: fgrep.pl --replace="bar" "foo"
#        fgrep.pl "string" ".*\.html"
#
# BUGS: if replacement string contains invalid characters
#       nothing gets done. Have to find a way to escape
#       all characters which might be used by Perl's
#       s/// operator
#
# LICENSE: GPL

use File::Find;        # find();
use File::Basename;    # basename();
use Getopt::Long;
Getopt::Long::Configure('bundling');

use strict;
$|++;

my $DEBUG = 0;

my $EXCEPTION_LIST = "(\\.soc|\\.sock|\\.so|\\.o|\\.swp)\$";

# some colors:

my $RED   = "\033[1;31m";
my $NORM  = "\033[0;39m";
my $GREEN = "\033[0;32m";
my $BLUE  = "\033[0;34m";

# -------------------------------------------------------------------
#           NO NEED TO MODIFY ANYTHING PASS THIS LINE               #
# -------------------------------------------------------------------

my $usage =
  "Usage:
fgrep.pl [-i,--ignore-case] [-f,--file-pattern=\"REGEX\"] [-r,--replace=\"replacement\"] <-s,--string=\"string\">
fgrep.pl <\"string to find\"> [\"REGEX file pattern\"] [\"replacement string\"]

NOTE use quotes to avoid the shell expanding your REGEX

";

my $this_string = undef;
my $that_string = undef;
my $f_pattern   = undef;
my $IGNORECASE  = 0;

GetOptions(

    'D|debug'          => \$DEBUG,
    'f|file-pattern=s' => \$f_pattern,
    's|string=s'       => \$this_string,
    'r|replace=s'      => \$that_string,
    'i|ignore-case'    => \$IGNORECASE,
  )
  and (not defined $this_string and $this_string = shift)
  and (not defined $f_pattern   and $f_pattern   = shift)
  and (not defined $that_string and $that_string = shift);

print STDERR ($usage) and die("Sorry. Can't search for (nul)
")
  if (not defined($this_string) or $this_string =~ m/^\s*$/);

if (defined($f_pattern) and $f_pattern =~ m#^[^\\]\.#)
{
    print STDERR
      "WARNING: using a dot in file pattern can match too many files. Escape dots with '\.'.
 Waiting 5 seconds before continuing
 Press CTRL+C to abort script execution
";
    sleep(5);
}

if (not defined($f_pattern))
{
    print STDERR "All files chosen
";
    $f_pattern = ".*";
}

$that_string = _clean_string($that_string) if (defined($that_string));
$this_string = _clean_string($this_string);

if ($DEBUG > 0)
{
    print STDERR "search for: '$this_string' 
";
    print STDERR "replace with: '$that_string' 
" if (defined($that_string));
    print STDERR "file pattern: '$f_pattern' 
"   if (defined($f_pattern));
    print STDERR "
";
    print STDERR "$RED DEBUG in place... pausing for 5 seconds$NORM
";
    sleep(5);
}

# main()
if ($this_string =~ /[[:alnum:]\.\_\-\(\)\[\]\{\}\"\']+/)
{
    _process_files(".");
}
else
{
    print STDERR ($usage);
    exit 1;
}
exit 0;

# supporting functions

sub _clean_string
{
    my $str = shift;
    return undef if (not defined $str);

    $str =~ s,\|,\\|,g;    # take care of |
    $str =~ s/\\$//g;      # take care of ending \

    return $str;
}

sub _process_files
{

    # uses find() to recur thru directories
    my $ROOT = shift;

    my %opt = (wanted => \&_process_file, no_chdir => 1);

    find(\%opt, $ROOT);
}

sub _is_binary
{

    # returns 1 if true
    my $file = shift;
    print STDERR ("is_binary() called: $file
") if ($DEBUG);
    my $file_t = qx/file "$file"/; # FIXME very expensive call. re-write in Perl
    if ($file_t =~ m/(text\s+executable|\btext\b|\s+script\b)/i)
    {
        return 0;
    }
    print STDERR ("binary file
") if ($DEBUG);
    return 1;
}

sub _process_file
{
    print STDERR ("Processing : ", $_, "
") if ($DEBUG);
    if (    $_ =~ m($f_pattern)
        and -r $_
        and basename($_) !~ m($EXCEPTION_LIST)
        and !_is_binary($_))
    {
        my $_file = $_;
        print STDERR ("opening $_file
") if ($DEBUG);
        my $_file_tmp = "$_file.$$.tmp";

        my $modified = 0;
        my $i        = 0;

        if (-f $_file_tmp)
        {
            unlink($_file_tmp)
              or die("Could not remove file $_file_tmp. $!
");
        }

        open(FILE, "<$_file") or die "could not open $_file. $!
";
        my $line='';
        while ($line = <FILE>)
        {
            $i++;
            if (defined($that_string))
            {
                # TODO cleanup
                if ($IGNORECASE and ($line =~ s|$this_string|$that_string|gi))
                {
                    my $_local = $line;    # beautify display
                    $_local =~ s/^\s+//;
                    print STDOUT "$GREEN $_file [$i]:$NORM $_local";
                    $modified = 1;
                }
                elsif ($line =~ s|$this_string|$that_string|g)
                {
                    my $_local = $line;    # beautify display
                    $_local =~ s/^\s+//;
                    print STDOUT "$GREEN $_file [$i]:$NORM $_local";
                    $modified = 1;
                }
                open(NEWFILE, ">>$_file_tmp")
                  or die("could not write to $_file_tmp. $!
");
                print NEWFILE $_;
                close(NEWFILE);
            }
            else
            {
                # TODO cleanup
                if ($IGNORECASE
                    and ($line =~ m|$this_string|gi))
                {
                    my $_local = $line;
                    $_local =~ s/^\s+//;    # beautify display
                    print STDOUT "$BLUE $_file [$i]:$NORM $_local";
                }
                elsif ($line =~ m|$this_string|g)
                {
                    my $_local = $line;
                    $_local =~ s/^\s+//;    # beautify display
                    print STDOUT "$BLUE $_file [$i]:$NORM $_local";
                }
            }
        }
        close(FILE);
        if ($modified)
        {
            if (-r "$_file_tmp")
            {
                rename("$_file_tmp", $_file);
            }
            else
            {
                die("Cannot read file $_file_tmp eventhough we created it? $!
"
                );
            }
            $modified = 0;    # just in case...
        }

        # cleanup
        if (-f $_file_tmp)
        {

            #DEBUG warn "Removing left-over file $_file_tmp
";
            unlink($_file_tmp)
              or die("Could not remove file $_file_tmp. $!
");
        }
    }
}


Advertisement