Как я могу удалить строки, которые включают subStr1 и subStr2 в большом файле? - PullRequest
1 голос
/ 10 февраля 2010

Как удалить целые строки, включающие subStr1 и subStr2, в большой файл и сохранить как новый файл меньшего размера.

Часть содержимого моего файла ниже.

12-23 20:27:35:265   GetVariable [Tunnel]    INFO  iVid = 536876042 data [Reruen] = System.Object[]
12-23 20:27:35:265   GetVariable [Tunnel]    INFO  iVid = 536876043 data [Reruen] = System.Object[]
12-23 20:27:33:718   SendEvent [Link]    INFO  eventID = 268435564
12-23 20:27:33:718   WaferMove [Link]    INFO  waferNumber = 122253 UNIT_ID dest = UNIT_ID_LL_A  slot = 1 bool isStarted = False
12-23 20:27:35:265   GetVariable [Tunnel]    INFO  iVid = 536876042 data [Reruen] = System.Object[]
12-23 20:27:35:265   GetVariable [Tunnel]    INFO  iVid = 536876043 data [Reruen] = System.Object[]
12-23 20:27:33:765   WaferMove(d) [Link]    INFO  waferNumber = 122253 UNIT_ID dest = UNIT_ID_LL_A  slot = 1 bool isStarted = False

И я хочу удалить все строки, включая GetVariable [Tunnel] и System.Object[] как строки ниже. БЛАГОДАРНОСТЬ.

12-23 20:27:35:265   GetVariable [Tunnel]    INFO  iVid = 536876043 data [Reruen] = System.Object[]

Ответы [ 6 ]

3 голосов
/ 10 февраля 2010

Используйте Переключатель Perl -i для редактирования на месте:

$ perl -i.bak -ne 'print unless /GetVariable\s+\[Tunnel]/ &&
                                /System.Object\[]/' file.log

Это оставит резервную копию вашего оригинала в file.log.bak, а отфильтрованная версия будет в file.log.

2 голосов
/ 10 февраля 2010

Извините за то, что это не Perl ответ, но я бы просто спонтанно использовал grep:

grep -v "GetVariable \[Tunnel\].*System\.Object\[\]" infile > outfile

Это может быть сделано с использованием Perl следующим образом:

perl -wne'print unless m/GetVariable \[Tunnel\].*System\.Object\[\]/' < infile > outfile
2 голосов
/ 10 февраля 2010
perl -ne 'm/\QGetVariable [Tunnel]\E.*?\QSystem.Object[]\E/ || print;' data.log > data.log.new

Затем просто переименуйте data.log.new в data.log.

2 голосов
/ 10 февраля 2010

Если вы можете позволить себе иметь копию файла (что, вероятно, безопаснее сделать), вы можете открыть два файла (один для чтения исходного файла, другой для записи в файл результатов) и пропустить строки, в которых вы найдете матч:

open(ORIG, '<', 'orig.txt');
open(RESULT, '>', 'result.txt');
while(my $line = <ORIG>) {
  # fine tune this
  next if $line =~ /GetVariable\s+\[Tunnel\].*System\.Object\[\]/;
  print RESULT $line;
}
close ORIG;
close RESULT;

Я не пробовал скрипт, поэтому сначала проверьте его на примере файла.

Редактировать: вам нужно настроить регулярное выражение. поиграй с ним немного.

1 голос
/ 11 февраля 2010

См. Ответ perlfaq5 на Как изменить, удалить или вставить строку в файл или добавить в начало файла? :


Как изменить, удалить или вставить строку в файл или добавить в начало файла?

(предоставлено Брайаном Д. Фой)

Основная идея вставки, изменения или удаления строки из текстового файла заключается в чтении и печати файла до точки, в которую вы хотите внести изменения, внесении изменений, затем чтении и печати остальной части файла. Perl не обеспечивает произвольный доступ к строкам (особенно с учетом того, что разделитель ввода записей $ / является изменяемым), хотя такие модули, как Tie :: File, могут имитировать его.

Программа Perl, выполняющая эти задачи, принимает базовую форму открытия файла, печати его строк и затем закрытия файла:

open my $in,  '<',  $file      or die "Can't read old file: $!";
open my $out, '>', "$file.new" or die "Can't write new file: $!";

while( <$in> )
    {
    print $out $_;
    }

закрыть $ out; В этой базовой форме добавьте части, которые вам нужны для вставки, изменения или удаления строк.

Чтобы добавить строки в начало, напечатайте эти строки перед тем, как войти в цикл, который печатает существующие строки.

open my $in,  '<',  $file      or die "Can't read old file: $!";
open my $out, '>', "$file.new" or die "Can't write new file: $!";

print $out "# Add this line to the top\n"; # <--- HERE'S THE MAGIC

while( <$in> )
    {
    print $out $_;
    }

закрыть $ out; Чтобы изменить существующие строки, вставьте код для изменения строк внутри цикла while. В этом случае код находит все версии "perl" в нижнем и верхнем регистре. Это происходит для каждой строки, поэтому убедитесь, что вы должны делать это на каждой строке!

open my $in,  '<',  $file      or die "Can't read old file: $!";
open my $out, '>', "$file.new" or die "Can't write new file: $!";

print $out "# Add this line to the top\n";

while( <$in> )
    {
    s/\b(perl)\b/Perl/g;
    print $out $_;
    }

закрыть $ out; Чтобы изменить только определенную строку, полезно ввести номер строки ввода $. Сначала прочитайте и распечатайте строки до той, которую хотите изменить. Затем прочитайте единственную строку, которую вы хотите изменить, измените ее и напечатайте. После этого прочитайте остальные строки и напечатайте:

while( <$in> )   # print the lines before the change
    {
    print $out $_;
    last if $. == 4; # line number before change
    }

my $line = <$in>;
$line =~ s/\b(perl)\b/Perl/g;
print $out $line;

while( <$in> )   # print the rest of the lines
    {
    print $out $_;
    }

Чтобы пропустить строки, используйте циклические элементы управления. Следующий в этом примере пропускает строки комментариев, а последний останавливает всю обработку, когда встречает либо END , либо DATA .

while( <$in> )
    {
    next if /^\s+#/;             # skip comment lines
    last if /^__(END|DATA)__$/;  # stop at end of code marker
    print $out $_;
    }

Сделайте то же самое, чтобы удалить определенную строку, используя next, чтобы пропустить строки, которые вы не хотите показывать в выводе. Этот пример пропускает каждую пятую строку:

while( <$in> )
    {
    next unless $. % 5;
    print $out $_;
    }

Если, по какой-то странной причине, вы действительно хотите видеть весь файл сразу, а не обрабатывать построчно, вы можете вставить его (если вы можете поместить все это в память!):

open my $in,  '<',  $file      or die "Can't read old file: $!"
open my $out, '>', "$file.new" or die "Can't write new file: $!";

my @lines = do { local $/; <$in> }; # slurp!

    # do your magic here

print $out @lines;

Модули, такие как File :: Slurp и Tie :: File, также могут помочь с этим. Если вы можете, однако, не читать весь файл сразу. Perl не вернет эту память операционной системе, пока процесс не завершится.

Вы также можете использовать однострочники Perl для изменения файла на месте. Следующее меняет все 'Fred' на 'Barney' в inFile.txt, перезаписывая файл новым содержимым. С ключом -p Perl оборачивает цикл while вокруг кода, который вы указали с помощью -e, а -i включает редактирование на месте. Текущая строка в $ . С помощью -p Perl автоматически печатает значение $ в конце цикла. Смотрите perlrun для более подробной информации.

perl -pi -e 's/Fred/Barney/' inFile.txt

Чтобы сделать резервную копию файла inFile.txt, укажите -i расширение файла для добавления:

perl -pi.bak -e 's/Fred/Barney/' inFile.txt

Чтобы изменить только пятую строку, вы можете добавить тестовую проверку $., Номер строки ввода, а затем выполнять операцию только после прохождения теста:

perl -pi -e 's/Fred/Barney/ if $. == 5' inFile.txt

Чтобы добавить строки перед определенной строкой, вы можете добавить строку (или строки!) До того, как Perl напечатает $ _:

perl -pi -e 'print "Put before third line\n" if $. == 3' inFile.txt

Вы даже можете добавить строку в начало файла, поскольку текущая строка печатается в конце цикла:

perl -pi -e 'print "Put before first line\n" if $. == 1' inFile.txt

Чтобы вставить строку после той, которая уже есть в файле, используйте ключ -n. Это похоже на -p, за исключением того, что он не печатает $ _ в конце цикла, поэтому вы должны сделать это самостоятельно. В этом случае сначала напечатайте $ _, затем напечатайте строку, которую вы хотите добавить.

perl -ni -e 'print; print "Put after fifth line\n" if $. == 5' inFile.txt

Чтобы удалить строки, напечатайте только те, которые вы хотите.

perl -ni -e 'print unless /d/' inFile.txt

    ... or ...

perl -pi -e 'next unless /d/' inFile.txt
1 голос
/ 10 февраля 2010
while (<>) {
    chomp;
    next if (/GetVariable \[Tunnel\]/ && /System.Object\[\]/);
    print $_ ."\n";

}

в командной строке

$ perl myscript.pl inputfile > newfile

вышеописанное работает также для «System.Object []», который предшествует «GetVariable [Tunnel]», и не удаляет строки, в которых есть только один из этих шаблонов.

или

perl -ne 'print if($_!~/GetVariable \[Tunnel\]/ && $_ !~ /System.Object\[\]/)' file
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...