awk '/[0-9]+ of [0-9]+ DOCUMENTS/{g++} { print $0 > g".txt"}' file
Пользователям OSX потребуется
blockquote>gawk
, так как встроенныйawk
приведет к ошибке, напримерawk: illegal statement at source line 1
Ruby (1.9 +)
#!/usr/bin/env ruby g=1 f=File.open(g.to_s + ".txt","w") open("file").each do |line| if line[/\d+ of \d+ DOCUMENTS/] f.close g+=1 f=File.open(g.to_s + ".txt","w") end f.print line end
Осложнение, что вам нужна глобальная замена, но только внутри шаблонов маркеров, может быть обработано путем захвата этой подстроки и выполнения регулярного выражения в ней в заменяющей части
my $s = q(a1b x and x c2d x more x a22b x again x c33d x and x);
$s =~ s/a.*?b\K(.*?)(?=c.*?d)/$1=~s{x}{y}gr/eg;
say $s;
Я использую \K
после левой шаблон маркера (a.*?b
) для отбрасывания предыдущих совпадений и просмотра шаблона правого маркера (c.*?d
), чтобы не копировать их вокруг, но для простоты вы можете захватить их и использовать числовые переменные ([116 ]) для них в замен.
Рассмотрите возможность захвата правого маркера (вместо предвкушения), если шаблон повторяется; тогда для дополнительной копии данных подшаблон не сканируется повторно, и все регулярные выражения чище и в принципе безопаснее (может ли правый маркер содержать левый маркер?). Это усложняет замену, где $2
нужно сохранить перед новым регулярным выражением, так как оно в нем сбрасывается.
Обратите внимание на модификатор /r
в регулярном выражении заменяющей части: кроме того, что он очень удобен, он также позволяет нам использовать s///
для переменной $1
, что в противном случае мы не могли бы сделать, поскольку она только для чтения. [1116 ]
Если это часть более сложной обработки регулярных выражений, обратите внимание, что упреждение является утверждением нулевой ширины , поэтому движок не использует этот шаблон и не пропускает его. Это имеет значение, если весь шаблон повторяется: если возможно, что правый маркер содержит левый маркер, вы должны захватить его, чтобы двигатель прошел мимо него для следующего матча, чтобы левый маркер был первым для него.
Это работает с переменными для шаблонов маркеров, которые вы любезно используете
my $start = qr/a.*?b/;
my $end = qr/c.*?d/;
my $s = q(a1b x and x c2d x more x a22b x again x c33d x and x);
$s =~ s/$start\K (.*?) (?=$end)/ $1 =~ s{x}{y}gr /egx;
say $s;
, где я размечал шаблоны для удобства чтения, благодаря /x
. Это печатает
a1b y and y c2d x more x a22b y again y c33d x and x
Вы можете использовать /e
, модифицированный для выполнения кода (для каждого совпадения отдельно) для генерации строки замены:
use strict;
use warnings;
my $start_regex = qr/a.*?b/;
my $end_regex = qr/c.*?d/;
my $string = 'a1b x c2d x a345b qqxxxc678d xx abxcd';
$string =~ s/($start_regex)(.*?)($end_regex)/ my ($start_match, $middle_match, $end_match) = ($1, $2, $3); $middle_match =~ s!x!y!g; $start_match . $middle_match . $end_match /eg;
print $string, "\n";
Распечатает
a1b y c2d x a345b qqyyyc678d xx abycd
Обратите внимание на альтернативу разделитель регулярных выражений s!!!
во внутреннем регулярном выражении.
Важно хранить $1
, $2
и $3
внешнего соответствия регулярному выражению во временных переменных, так как они будут потеряны, когда вы выполните другое регулярное выражение в коде замены.