Solved

rm a word in bunch of file

Posted on 2004-11-01
806 Views
Last Modified: 2012-06-27
I have many files in my directory with the string xxxxxx in all of them.
How can i use perl script to rome this string from all of them.

Thanks
0
Question by:komlaaa
    20 Comments
     
    LVL 16

    Expert Comment

    by:manav_mathur
    Is it really necessary to use PERL??

    This can be done through a simple shell script.

    sed 's/run/walk/g' < logfile1.dat > logfile2.dat   will replace all occurences of "run" with "walk" in the file logfile1.dat and store the result in logfile1.dat.

    You could then create a wrapper for feeding all files here.

    Manav
    0
     

    Author Comment

    by:komlaaa
    it not just one file, i think using perl should be easy.

    here my version but not working properly.
    ============== MY VERSION ==============
    #!/usr/local/bin/perl



    @Files = glob "*";

    foreach $file (@Files)
    {
        open(IN, ">$file");
        $string = <IN>;
        ($st = $_) =~ s/xxxxxx$//;
        open(OUT, ">$file");
        print OUT "$st";
        close OUT;
        close IN;
    }


    0
     
    LVL 16

    Expert Comment

    by:manav_mathur
    komlaa,

    open (IN,">$file") ;

    should be

    open(IN, "< $file") ;

    You have to use a < , not a >

    Manav
    0
     

    Author Comment

    by:komlaaa
    i made the change and i am having error message:

    Global symbol "@Files" requires explicit package name at .//replace.pl line 6.
    BEGIN not safe after errors--compilation aborted at .//replace.pl line 6.
    0
     
    LVL 16

    Expert Comment

    by:manav_mathur
    @Files = glob "*";
    foreach $file (@Files)
    {
        open(IN, "<$file");
          open(OUT, ">$file.tmp");
        while (<IN>) {
        ($st = $_) =~ s/xxxx//g;
        print OUT $st;
          }
        close OUT;
        close IN;
        system "mv $file.tmp $file" ;
    }


    This should work

    Manav
    0
     
    LVL 16

    Expert Comment

    by:manav_mathur
    use
    my @Files = glob("*") ;

    instead of
    @Files = glob("*") ;

    Manav
    0
     
    LVL 16

    Expert Comment

    by:manav_mathur
    By the way,
    small errata in my forsi post

    >sed 's/run/walk/g' < logfile1.dat > logfile2.dat   will replace all occurences of "run" with "walk" in the file logfile1.dat and >store the result in logfile1.dat.

    The results will be stored in logfile2.dat and not logfile2.dat

    Cheers
    Manav

    0
     
    LVL 16

    Expert Comment

    by:manav_mathur
    Komlaa,

    Do not try updating the same file for input and output. I tried that and it doent work.

    This is a safer method. If you dont wanna use system, after the script runs, you can schedule a script that takes care of all the .tmp files. or you can do them yourself. By the way, as long as you are on *NIX, I dont see any harm in the script that I've given you .



    Cheers
    Manav

    0
     
    LVL 16

    Expert Comment

    by:manav_mathur
    use strict;                           #to prevent variable declaration errors
    use warnings;                     #like the one you were getting Global symbol blah blah requires explcit blah blah
    my @Files = glob "*";
    foreach my $file (@Files)
    {
        open(IN, "<$file");
          open(OUT, ">$file.tmp");
        while (<IN>) {
        (my $st = $_) =~ s/xxxxx$//g;
        print OUT $st;
          }
        close OUT;
        close IN;
        system "mv $file.tmp $file" ;
    }

    is not giving me any errors.

    Cheers
    Manav
    0
     

    Author Comment

    by:komlaaa
    i tryed your code above but i am still having the same error
    0
     
    LVL 48

    Expert Comment

    by:Tintin
    Using a shell script, you'd do:

    #!/bin/sh

    for file in *
    do
       sed 's/xxxx//' $file >/tmp/$$ && mv /tmp/$$ $file
    done

    or a Perl script (or command line to be precise, you'd do

    perl -i.bak -pe 's/xxxx//' *

    The -i.bak will create a backup of all files changed.
    0
     
    LVL 38

    Expert Comment

    by:wesly_chen
    Hi,

       For Tintin's script, it may need to be modified as follow:
    ----------
    #!/bin/sh

    FILES=`cat filelist.txt`

    for file in $FILES
    do
       sed 's/xxxx//' $file >/tmp/$$ && mv /tmp/$$ $file
    done
    ---------
    Where filelist.txt contains all the files you want to replace strings.

       I like Tintin's script which is clear and neat.

    Wesly
       
    0
     

    Author Comment

    by:komlaaa
    why specifically filelist.txt... i have such file, in my dir
    0
     

    Author Comment

    by:komlaaa
    sorry i meant i have no such file called filelist.txt in my dir!! Or it is a key word?
    0
     
    LVL 38

    Expert Comment

    by:wesly_chen
    Hi,

       filelist.txt is used more for the files in different directories. It gives you fexibility.

    Wesly
    0
     
    LVL 38

    Expert Comment

    by:wesly_chen
    Hi,

       You need to create the "filelist.txt" if you have files in different directories for string replacement.

    Wesly
    0
     

    Accepted Solution

    by:
    This will do it : )

    perl -pi -e ' s/some/other/ig; ' *
    Or in your case  ::

    perl -pi -e ' s/xxxxxx//; ' *

    Dhruv
    0
     
    LVL 48

    Expert Comment

    by:Tintin
    Aqui10.

    And your answer differs from my by....?
    0
     
    LVL 5

    Assisted Solution

    by:ITcrow
    Perl command line.
    perl -i.old -p -e 's/foo/bar/g' *

    There are some obvious advantages of using 'xargs'
    find . -type f ¦ xargs perl -i.old -p -e 's/foo/bar/g'

    Perl elaborative, should be something like: ( Untested Code )
    foreach (glob "*") {
       open( SRC, $_ ) || die "$!";
        @lines = <SRC>; close( SRC );
        open( DST, $_ ) || die "$!";
        foreach( @lines ) {
            s/foo/bar/g;
             print DST "$_";
        }
        close( DST );
    }
    0
     
    LVL 3

    Expert Comment

    by:nochkin
    Why so complicated? If you have recent enough sed then you can do this one-liner:

    sed -i.oldtemp -s "s/word//"  *

    That will remove "word" from all files in the current directory.
    Then you will have manye *.oldtemp files as backup of your originals. If everything went okay then you can remove all *.oldtemp files.
    0

    Write Comment

    Please enter a first name

    Please enter a last name

    We will never share this with anyone.

    Featured Post

    IT Security CISA, CISSP & CISM Certification

    Master the advanced techniques required to protect network resources from external threats with the IT Cyber Security bundle. Built around industry best-practice guidelines, the IT Cyber Security bundle consists of three in-depth courses.

    Email validation in proper way is  very important validation required in any web pages. This code is self explainable except that Regular Expression which I used for pattern matching. I originally published as a thread on my website : http://www…
    I have been pestered over the years to produce and distribute regular data extracts, and often the request have explicitly requested the data be emailed as an Excel attachement; specifically Excel, as it appears: CSV files confuse (no Red or Green h…
    Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…
    Need more eyes on your posted question? Go ahead and follow the quick steps in this video to learn how to Request Attention to your question. *Log into your Experts Exchange account *Find the question you want to Request Attention for *Go to the e…

    857 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    9 Experts available now in Live!

    Get 1:1 Help Now