Без лишних слов привожу эту строку:
$ perl -w -i.bak -pe 'BEGIN {$/="},\r"} s/^\n\{[\d\D]+?,6,2,2,\d+,\d,I,"",(?:109|0),[\d\D]+\},\r$//' ./*.lgp
Кажется сложным только на первый взгляд. Давайте опишем назначение элементов этой команды. Для того, чтобы было проще понять описание, ниже приведён фрагмент журнал регистрации. В разборе его формата мне помогла эта статья: infostart.ru/1c/articles/182061/
- perl -w Вызов интерпретатора Perl. С ключём -w он будет выводить предупреждения. Если Perl на вашем компьютере ещё не установлен, рекомендую установить Git Bash;
- -i.bak Ключ -i[расширение] указывает на то что файлы, переданные в качестве аргумента командной строки, будут отредактированы. Если задать любое расширение (в нашем случае .bak), то после редактирования файлов на диске останутся их резервные копии с этим расширением;
- -pe С ключём -p Perl генерирует простую программу: while (<>) { print; }. А то, что следует после ключа -e, эту программу дополняет. Фактически Perl исполнит следующий скрипт:
$/="},\r"
while (<>) {
s/^\n\{[\d\D]+?,6,2,2,\d+,\d,I,"",(?:109|0),[\d\D]+\},\r$//;
print;
}
Здесь требуются некоторые пояснения. В первой строке мы устанавливаем значение специальной переменной $/, которая хранит разделитель записей. В цикле while (<>) Perl читает переданные файлы построчно. По умолчанию разделителем записей является символ новой строки. Если мы посмотрим на формат журнала регистрации (выше), то увидим, что разделителем записей является комбинация символов },\r (где \r - возврат каретки), поэтому мы переопределяем $/.
Добавлю, что Perl имеет специальную опцию командной строки для установки разделителя записей: -0. Но, к сожалению, с помощью этой опции можно установить в качестве разделителя только один символ, поэтому нам приходится делать это в коде: BEGIN {$/="},\r"}.
Идём далее. Оператор s/[шаблон]/[замена]/ ищет совпадение с шаблоном и заменяет его. В нашем случае, если очередная запись совпадает с шаблоном ^\n\{[\d\D]+?,6,2,2,\d+,\d,I,"",(?:109|0),[\d\D]+\},\r$ , то эта запись исключается (заменяется пустой строкой).
Теперь разберём регулярное выражение:
Наша запись в журнале регистрации начинается с символа новой строки и фигурной скобки: ^\n\{ . Далее идет последовательность любых символов, включая символ новой строки: [\d\D]+? . Читаем любые символы до тех пор, пока не находим ,6,2,2,. Это идентификаторы, соответственно, пользователя, компьютера и приложения (см. разбор формата журнала). Далее идут два других числовых идентификатора, значения которых нас не интересуют. После них в записи к удалению мы ожидаем увидеть "I" (важность события журнала - "Информация"), пустой комментарий к событию и идентификатор метаданных, который может принимать значения 109 или 0. Заканчивается запись последовательностью любых символов, фигурной скобкой, запятой и возвратом каретки: [\d\D]+\},\r$.
Вам потребуется отредактировать это регулярное выражение так, чтобы с ним совпадали записи, которые нужно удалить вам. Регулярное выражение должно быть достаточно строгим, чтобы исключить удаление лишних записей.
У команды, приведенной в начале статьи, есть один недостаток. Если мы посмотрим на журнал регистрации, то увидим, что первая и последняя записи отличаются от остальных. Первая запись включает заголовок файла (1CV8LOG(ver 2.0)...), а последняя не заканчивается запятой. Эти записи не соответствуют регулярному выражению, а поэтому не будут удалены, даже если подходят по остальным параметрам. Если мы удалим эти записи, то нарушим формат файла журнала регистрации.
Если необходимо, чтобы были удалены абсолютно все заданные записи, даже если они находятся на первой или последней позициях в файле, придётся быть более многословным:
#!/usr/bin/perl -w
# Удаление записей из журнала регистрации
use strict;
$^I = ".bak"; # С бэкапом файлов
#$^I = ""; # ... или без него
$/ = "},\r";
my $hdr; # Заголовок файла
while (<>) {
my $m = /[\d\D]+?,6,2,2,\d+,\d,I,"",(?:109|0),[\d\D]+/;
if ($. == 1 && $m) { # Совпадение в первой записи, будет нужно вернуть заголовок
/[^{]*/;
$hdr = $&;
} elsif (!$m) {
chomp;
if (defined $hdr) {
print $hdr . substr($_, 1); # Добавляем заголовок, удаляем пустую строку
undef $hdr;
} else {
print $. == 1 ? $_ : $/ . $_;
}
} elsif (eof && $m) { # Последняя скобка в файле без запятой
print "}";
}
close ARGV if eof; # Чтобы сбросить счетчик '$.'
}
Сохраняем этот скрипт в файл (например, clnlgp.plx), делаем файл исполняемым и выполняем, передавая в качестве аргумента маску файлов журнала регистрации:
$ chmod +x clnlgp.plx
$ clnlgp.plx D:/_1cv8log/*.lgp