С Awk и Grep мне нужно напечатать несколько строк - PullRequest
0 голосов
/ 30 ноября 2018

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

start pattern1

line1
Matching pattern can be here
line2
Matching Pattern can be here
line3
line4
...
end pattern1
.
start pattern1
line1
line2
start pattern1

start pattern1
line1
Matching pattern can be here
line2
start pattern1

, поэтому из perl мне нужно найти строки между начальным шаблоном1 ... end pattern1, для этого я использую команду awk для grep

 $cmd = q(awk '/start pattern1/,end pattern1 /' x.file );
 $n1 = system($cmd);

Для этого вывода работает нормально, ниже вывод,

start pattern1
line1
**Matching pattern can be here**
line2
**Matching Pattern can be here**
...
end pattern1

Но в файлах у меня есть 1000 излинии, как это, поэтому мне нужно grep те линии, которые имеют шаблон соответствия.то есть мне нужно grep только те начальные строки шаблона, чтобы конечные строки шаблона имели соответствующий шаблон

Для этого я попытался

 $cmd = q(awk '/start pattern1/,end pattern1 /' x.file | grep  '$n2\|line4');
 $n1 = system($cmd);

Но когда я использую вышеуказанную команду, я не вижу никакого выводаЗдесь $ n2 содержит некоторый шаблон, извлеченный из другого файла.

Если я использую шаблон прямого совпадения вместо $ n2, он работает нормально, почему я не могу использовать здесь $ n2?

Примечание: яЯ использую это в скрипте Perl

Из команды Awk я получаю все строки между начальным pattern1 ... end pattern1, но у меня есть 1000 таких отпечатков, поэтому мне нужно связку строк начального pattern1 дляконечный шаблон 1 из этого, который сопоставляется с соответствующим шаблоном

Ожидаемый результат, когда я это сделаю,

start pattern1
line1
Matching pattern can be here
line2
Matching Pattern can be here
line3
line4
...
end pattern1 

 start pattern1
    line1
    Matching pattern can be here
    line2
    start pattern1

1 Ответ

0 голосов
/ 30 ноября 2018

Нет необходимости вызывать awk изнутри perl, поскольку perl намного мощнее, чем awk.

Мне не ясно, хотите ли вы каждую строку между start pattern1 и end pattern1если есть хотя бы одно совпадение внутри, или просто совпадающих строк.

Если каждая строка между началом и концом совпадает:

my @blocks = join("",<>)=~/start pattern1\s*(.*?)end pattern1/gsi;
print grep /matching pattern/i, @blocks;

Если каждая строка ВКЛЮЧЕНАstart | end pattern1:

my @blocks = join("",<>)=~/(start pattern1.*?end pattern1\s*)/gsi;

Если просто строки с / совпадающим шаблоном / между началом и концом:

print grep { /start pattern1/i../end pattern1/i and /matching pattern/i } <>;

Поместите это в файл program.pl и запустите:

perl program.pl inputfile > outputfile

Может потребоваться некоторое объяснение: join("",<>) возвращает весь входной файл в виде одной многострочной строки.Модификаторы /gsi означают: g соответствует глобально, так что массив @block будет содержать то, что соответствует круглым скобкам, один элемент массива для каждого соответствия (без g массив @block просто получит первый блокстрок), s означает, что . также соответствует символам новой строки, которые в противном случае не совпадают, а i соответствует игнорированию регистра (не видит различий между буквами az и AZ).Знак вопроса в .*? означает несжатое сопоставление каждого символа, то есть совпадение до следующего end pattern1, а не до последнего.<> возвращает строки inputfile (аргументы после perl program.pl) в виде массива строк... является оператором триггера, который имеет значение true после того, как левая сторона становится истинным, и ложь, после того как правая сторона становится истинной, и остается ложной, пока левая сторона снова не станет истинной и т. Д.

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