2015-10-21 2 views
2

У меня есть большой файл 5000+ строк, который имеет повторяющийся рисунок, как показано ниже:печатные линии между узорами отдельных отдельными файлами

ABC 
111 
222 
333 
XYZ 

ABC 
444 
555 
666 
777 
XYZ 

.. 
.. 

ABC 
777777777 
888888888 
999999999 
222 
333 
111 
XYZ 

Я хотел бы, чтобы извлечь содержимое между каждым «ABC» и «XYZ» и записать его в отдельный файл.

Ex: file1 должен иметь

ABC 
111 
222 
333 
XYZ 

File2 должны иметь

ABC 
444 
555 
666 
777 
XYZ 

Filen должны иметь

ABC 
777777777 
888888888 
999999999 
222 
333 
111 
XYZ 

и так далее.

Как мы можем достичь этого? Я прочитал эти ниже потоки, но он пишет только один файл. Не помогло для моего дела.

How to select lines between two marker patterns which may occur multiple times with awk/sed

Print lines between two patterns to new file

ответ

2

Perl на помощь!

< bigfile perl -nwe 'print {$OUT} $_ 
         if (/ABC/ && do { open $OUT, ">", "file" . ++$i or die $!} 
          ) ... /XYZ/' 
  • n читает файл построчно
  • он только печатает, если между /ABC/ и /XYZ/
  • когда /ABC/ верно, то мы начинаем новый раздел, новый файл открыт и связанный с дескриптором файла $OUT. $i - номер файла.
+0

спасибо Choroba. Я сохраню этот скрипт perl и буду использовать его позже. Спасибо за ваше время и помог мне. – bala

+0

Красиво сделано; Я предлагаю использовать для файла дескриптор нечто иное, чем '$ {O}', потому что его легко путать с '$ {0}' (ноль). С флагом '-w' вы действительно получаете предупреждение здесь об использовании' $ i' только один раз (Perl v5.18.2); альтернативой исключению '-w' является добавление' BEGIN {$ i} '. Кроме того, учитывая, что строки открытия и закрытия диапазона ожидаются на разных линиях, лучше использовать '...', чем '..'. Правильно ли я предполагаю, что повторное использование одного и того же файла неявно закрывает ранее открытый файл ? – mklement0

+1

@ mklement0: хорошие моменты. – choroba

4
awk '/^ABC/{file="file"c++}{print >>file}' a 
+1

Хорошо, вы могли бы добавить конец * session *, чтобы избежать пустых строк после 'XYZ', например' awk '/^ABC/{file = "file" C++; w = 1} w {print >> file}/^ XYZ/{w = 0} 'a' – NeronLeVelu

+1

вот так; awk '/^ABC/{file = "file" C++; a = 1} a {print >> file}/^ XYZ/{a = 0}' a – bian

+0

вправо, вы быстро, мне еще нужно было отредактировать/вставить ответ :-) – NeronLeVelu

1
awk ' 
    # setup our output file name file0, file1, file2, ... 
    $0 == "ABC"{if (i) {close(f)};f="file"i++;}; 
    # use inclusive range match 
    $0 == "ABC",$0 == "XYZ"{print > f} 
' 
+0

Спасибо за обновление, но из того, что я понимаю, вам не нужно явно обрезать файл - просто используйте 'print> f' вместо' print >> f'. Операторы перенаправления внутри 'awk' работают иначе, чем в оболочке: в скрипте' awk', используя '>' на каждой итерации НЕ будет воссоздавать файл каждый раз; вместо этого он будет неявно открывать/усекать файл при первом доступе, а затем продолжать добавлять до тех пор, пока файл не будет закрыт (явно или неявно после завершения 'awk'). – mklement0

+1

@ mklement0 сладкий не знал этого. Я довольно с awk :-) – andlrc

+0

@ mklement0 уверен, но можете ли вы немного подробнее рассказать о том, что может произойти с незакрытым обработчиком? Я имею в виду, не будет ли он закрыт, когда awk закончится? – andlrc

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