2013-10-07 4 views
0

входного файлаPerl один лайнер, чтобы удалить многострочный

<section_begin> mxsqlc 


*** WARNING[13052] Cursor C is not fetched. 
<section_end> 
<section_begin> b2.lst 
* 


*** WARNING[13052] Cursor C is not fetched. 

0 errors, 1 warnings in SQL C file "b2.ppp". 
<section_end> 
<section_begin> b2s0 
SQLCODE=0 
SQLSTATE=00000 
a=10, b=abc, c=20 
SQLCODE=0 
SQLSTATE=00000 
a=10, b=abc  , c=10, d=xyz  
<section_end> 

ожидая выход без ниже линии.

<section_end> 
<section_begin> b2s0 

мой код

perl -ne 'print unless /^\<section_end\>(\s*|.*lst)?\s*$/' b2exp 

Она удаляет все <section_end> линии и не удаляет эту линию <section_begin> *.lst

+4

Поскольку вы не предпринимали никаких попыток совпадения? Может быть, вы хотите '/^ (\ s * |. * Lst)? \ S * $/i'. – Qtax

+0

Или может быть более ограничительным '/^

​​| begin>. * \. Lst) \ s * $ /'. –

+0

Я использовал то же самое. но не удача perl -ne 'print if /^(\s*|.*lst)?\s*$/i' b2exp возвращает mxsqlc *** ПРЕДУПРЕЖДЕНИЕ [ 13052] Курсор C не выбран. * *** ПРЕДУПРЕЖДЕНИЕ [13052] Курсор C не выбран. 0 ошибок, 1 предупреждение в файле SQL C «b2.ppp». b2s0 SQLCODE = 0 SQLSTATE = 00000 а = 10, б = аЬс, с = 20 SQLCODE = 0 SQLSTATE = 00000 а = 10, б = аЬс, с = 10, d = хуг. отсутствует :( – user2347191

ответ

1

держать его просто

perl -ne 'print unless /^\<section_/' b2exp 

немного сложнее

perl -ne 'print unless /^\<section_(end|begin)\>/' b2exp 

А, ваш вопрос непонятен. (Для меня, может быть, это на самом деле)

теперь я прочитал его как «У меня есть некоторые разделы, отмеченные с <section_begin> tagname в начале и </section_end> в конце. Я хочу, чтобы исключить участки с определенным тэгом, bs20 в примере. Я хочу, чтобы все остальные линии "

perl -ne 'BEGIN {$p=1} $p=0 if /section_begin.*b2s0/; print if $p; $p=1 if /<section_end>/;' ex.txt 
+0

ожидает выход ' mxsqlc *** ПРЕДУПРЕЖДЕНИЕ [13052] Курсор C не извлекается. * *** ПРЕДУПРЕЖДЕНИЕ [13052] Курсор C не извлекается. 0 ошибок, 1 предупреждений в SQL-C файла "b2.ppp". b2s0 SQLCODE = 0 SQLSTATE = 00000 а = 10, б = аЬс, с = 20 SQLCODE = 0 SQLSTATE = 00000 a = 10, b = abc, c = 10, d = xyz ' – user2347191

0

Если намерение состоит в том, чтобы объединить раздел с lst со следующей секцией (и удалить материал на ту же линию, после того, как начать тэг следующего секции), Я бы пошел с Awk.

awk '/<section_end>/ && lst { next } 
    /<section_begin>/ && lst { lst=0; next } 
    /<section_begin>.*lst/ {lst=1} 
    1' b2exp 

То же самое можно сделать и в Perl; простейшая однострочная линия с perl -0777 -pe 's/.../.../s' file будет намного менее эффективной с точки зрения памяти из-за буферизации.

perl -0777 -pe 's%(<section_begin>[^\n]*lst.*?)\n<section_end>\n<section_begin>[^\n]%$1%s' b2exp 

Это будет читать весь файл в память (-0777) и заменить регулярное выражение из нескольких строк. Жадный матч .*? сделает совпадение максимально коротким, т. Е. Не пройдет мимо матча на остальной части шаблона (новая строка, конечный тег, новая строка, начальный тег, а затем необязательные данные, не связанные с новой строкой). Мы также позаботимся о том, чтобы использовать [^\n], где мы хотим сохранить совпадения в одной строке, так как флаг /s превращает . в подстановочный знак, который также может соответствовать символам новой строки.

Смежные вопросы