71

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

Mark Harrison
  • 297,451
  • 125
  • 333
  • 465
Robert
  • 8,406
  • 9
  • 38
  • 57

5 Answers5

77

If your version of sed allows the -i.bak flag (edit in place):

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

If not, simply put it in a bash loop:

for file in *.txt
do
    sed '/line of text/d' "$file" > "$file".new_file.txt
done
fedorqui
  • 275,237
  • 103
  • 548
  • 598
ennuikiller
  • 46,381
  • 14
  • 112
  • 137
52

To find a pattern and remove the line containing the pattern below command can be used

find . -name "*" -type f | xargs sed -i -e '/<PATTERN>/d'

Example : if you want to remove the line containing word sleep in all the xml files

find . -name "*.xml" -type f | xargs sed -i -e '/sleep/d'

NOTE : Be careful before choosing a pattern as it will delete the line recursively in all the files in the current directory hierarchy :)

khyox
  • 1,276
  • 1
  • 20
  • 22
Sitesh
  • 1,816
  • 1
  • 18
  • 25
6

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 Brase
  • 78,112
  • 7
  • 148
  • 169
6
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
  • 297,451
  • 125
  • 333
  • 465
  • From this [link](http://www.kuro5hin.org/story/2009/3/9/191744/8407): both perl and sed are traditional NFA engines, so theoretically they shouldn't differ to greatly in their performance, but in reality perl has a large number of optimisations applied that make it perform well in common cases. – stephenmm Dec 13 '10 at 18:39
2

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
  • 122,029
  • 33
  • 303
  • 309