views:

1040

answers:

4

is there a simple way to remove the same line of text from a folder full of text documents at the command line?

A: 

I wrote a Perl script for this:

#!/usr/bin/perl

use IO::Handle;

my $pat = shift(@ARGV) or
    die("Usage: $0 pattern files\n");
die("Usage $0 pattern files\n")
    unless @ARGV;

foreach my $file (@ARGV) {
    my $io = new IO::Handle;
    open($io, $file) or
        die("Cannot read $file: $!\n");
    my @file = <$io>;
    close($io);
    foreach my $line (@file) {
        if($line =~ /$pat/o) {
            $line = '';
            $found = 1;
            last;
        }
    }
    if($found) {
        open($io, ">$file") or
            die("Cannot write $file: $!\n");
        print $io @file;
        close($io);
    }
}

Note that it removes lines based on a regex. If you wanted to do exact match, the inner foreach would look like:

foreach $line (@file) {
    chomp $line;
    if($line eq $pat) {
        $line = '';
        $found = 1;
        last;
    }
}
chaos
+7  A: 

sed -i.bak '/line of text/d' *

if your versoin of sed allows the -i.bak flag (edit in place). if not simply put it in a bash loop:

for file in $(ls *.txt)
do
sed '/line of text/d' $file > $file.new_file.txt
done
ennuikiller
+1 for the `-i.bak` gsed fu. Your `for loop` probably needs a `mv $file.new_file.txt $file` to match it.
nik
@Robert, If you miss the right sed, you can still do: `perl -pi.bak -e 's|line of text||g' \*`
nik
That leaves a blank line rather than deleting the line, right?
Ry4an
@Ry4an, I guess you are right on that. There is a way to catch the end-of-line along with the text -- but, I can't recall that.
nik
do I have to use a backslash before any control characters? what are they?
Robert
`$(ls *.txt)` is stupid (forks extra process, can't handle spaces in filenames). try `for file in *.txt` instead
hhaamu
+1  A: 

Consider grep -v:

for thefile in *.txt ; do
   grep -v "text to remove" $thefile > $thefile.$$.tmp
   mv $thefile.$$.tmp $thefile
done

Grep -v shows all lines except those that match, they go into a temp file, and then the tmpfile is moved back to the old file name.

Ry4an
A: 
perl -ni -e 'print if not /mystring/' *

This tells perl to loop over your file (-n), edit in place (-i), and print the line if it does not match your regular expression.

Somewhat related, here's a handy way to perform a substitution over several files.

perl -pi -e 's/something/other/' *
Mark Harrison