Perl для удаления строк из файла - PullRequest
0 голосов
/ 19 октября 2011

У меня есть файл, который выглядит как:

ATOM 2517 O   VAL 160 8.337  12.679  -2.487
ATOM 2518 OXT VAL 160 7.646  12.461  -0.386
TER 
ATOM 2519 N   VAL 161 -14.431  5.789 -25.371
ATOM 2520 H1  VAL 161 -15.336  5.698 -25.811
ATOM 2521 H2  VAL 161 -13.416 10.529  17.708
ATOM 2522 H3  VAL 161 -14.363  9.436  18.498
ATOM 2523 CA  VAL 161   4.400  9.233  16.454
ATOM 2524 HA  VAL 161   3.390  9.170  16.047

Я должен удалить "TER", строку перед "TER" и 3 строки после строки сразу после TER и сделать файл непрерывным, как это:

ATOM 2517 O   VAL 160   8.337 12.679  -2.487
ATOM 2519 N   VAL 161 -14.431  5.789 -25.371
ATOM 2523 CA  VAL 161   4.400  9.233  16.454
ATOM 2524 HA  VAL 161   3.390  9.170  16.047

Ответы [ 4 ]

3 голосов
/ 19 октября 2011

Простой построчный скрипт.

Использование: perl script.pl -i.bak fileglob

Например perl script.pl -i.bak File*MINvac.pdb

Это изменит оригиналфайл и сохраните резервную копию каждого файла с расширением .bak.Обратите внимание, что если TER строки появляются слишком близко к концу файла, это вызовет предупреждения.С другой стороны, также будут представлены другие решения.

Если вы не хотите сохранять резервные копии (будьте осторожны, поскольку изменения необратимы!), Используйте -i.

код:

#!/usr/bin/perl
use v5.10;
use strict;
use warnings;

my $prev;
while (<>) {
    if (/^TER/) {
        print scalar <>;  # print next line
        <> for 1 .. 3;    # skip 3 lines
        $prev = undef;    # remove previous line
    } else {
        print $prev if defined $prev;
        $prev = $_;
    }
    if (eof) {  # New file next iteration?
        print $prev;
        $prev = undef;
    }
}
0 голосов
/ 19 октября 2011

Итак, для каждого набора из 6 последовательных строк вы хотите отбросить все, кроме третьей строки , если вторая строка - TER?

TIMTOWTDI, но это должно работать:

my @queue;
while (<>) {
    push @queue, $_;
    @queue = $queue[2]  if @queue == 6 and $queue[1] =~ /^TER$/;
    print shift @queue  if @queue == 6;
}
print @queue;  # assume no TERs in last 4 lines
0 голосов
/ 19 октября 2011

Я понял, что должен был написать это на Perl, но теперь я уже написал это на Python.Я отправляю его в любом случае, так как это может оказаться полезным, не вижу в этом никакого вреда.

#!/usr/bin/python2.7
import sys
import glob
import os

try:
    dir = sys.argv[1]
except IndexError:
    print "Usage: "+sys.argv[0]+" dir"
    print "Example: "+sys.argv[0]+" /home/user/dir/"
    sys.exit(1)

for file in glob.glob(os.path.join(dir, 'File*_*MINvac.pdb')):
    fin = open(file, "r")
    content = fin.readlines()
    fin.close()

    for i in range(0, len(content)):
        try:
            if "TER" in content[i]:
                del content[i]
                del content[i-1]
                del content[i:i+3]
        except IndexError:
            break
    fout = open(file, "w")
    fout.writelines(content)
    fout.close()

Редактировать: Добавлена ​​поддержка нескольких файлов, как хотел OP.

0 голосов
/ 19 октября 2011
use strict;
use warnings;
use Tie::File;

my @array;

tie @array, 'Tie::File', 'myFile.txt' or die "Unable to tie file";

my %unwanted = map  { $_ => 1 }                # Hashify ...
               map  { $_-1, $_, $_+2 .. $_+4 } # ... the five lines ...
               grep { $array[$_] =~ /^TER/ }   # ... around 'TER'  ...
               0 .. $#array ;                  # ... in the file

# Remove the unwanted lines
@array = map { $array[$_] } grep { ! $unwanted{$_} } 0 .. $#array;

untie @array;  # The end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...