Разделите текстовый файл на несколько, когда шаблон появится с командной строкой в Linux

Я хочу разделить текстовый файл на несколько. Один новый файл каждый раз шаблон появляется. Пример: шаблоном будет PAT

Исходное содержание файла:

PAT --example html http://askubuntu.com/page01
ABC
DEF

PAT --example html http://askubuntu.com/page02
GHI
JKL

PAT --example html http://askubuntu.com/page03
MNO
PQR

(и так далее)

Исходный файл называют original.txt, как который я хотел бы получить файлы так:

$ cat page01.txt
ABC
DEF
$ cat page02.txt
GHI
JKL
$ cat page03.txt
MNO
PQR

(и так далее)

Идеально с командами как grep, awk... Переименование файлов вторично, но было бы плюс помочь классификации их.Заранее спасибо.

3
задан 1 October 2015 в 02:59

3 ответа

Вы могли использовать awk с некоторым перенаправлением:

awk -F/ '/^PAT/{close(file);file = $NF; next} /./{print >> file}' foo

результат:

$ head page0*
==> page01 <==
ABC
DEF    

==> page02 <==
GHI
JKL    

==> page03 <==
MNO
PQR

По существу, для каждой строки, начинающейся PAT, я сохраняю последнее поле (через разделителя полей /) переменная file и затем печатаю каждую непустую строку (/./ строки соответствий по крайней мере с одним символом) к имени, содержавшемуся в file.

Примечание, которое важно закрыть предыдущий файл в каждом цикле для предотвращения "makes too many open files" ошибка, когда существует "много" созданного файла.

5
ответ дан 1 December 2019 в 13:16

Также взгляните на csplit (1):

csplit --suppress-matched --prefix page --suffix-format %02d.txt original.txt '/^PAT/' '{*}'

файл Разделений orginal.txt в отдельные файлы, когда regex шаблон найден.

page00.txt
page01.txt
...
0
ответ дан 1 December 2019 в 13:16

Так как @muru бьют меня к awk решение, вот подход Perl (но @Muru использования вместо этого, это более просто и более эффективно):

perl -00ne 's#PAT.*/(.*)\n##; open($F,">","$1.txt"); s/\n\s*(\n|$)//g; 
            print $F "$_\n"' original.txt 

-00 делает perl абзацы обработки как строки: "строка" ("запись") является теперь абзацем, определенным пустой строкой. s#PAT.*/(.*)\n## удалит строку, запускающуюся с PAT от записи и круглых скобок получают последнее слово после / как $1.Then, мы открываемся $1.txt для записи (open($F,">","$1.txt")) с дескриптором файла $F. Следующий шаг, s/\n\s*\n//g; удаляет пустые строки и, наконец, текущая запись печатается к дескриптору файла $F с print $F "$_\n".


Использовать все после // как имя, попробуйте:

perl -00ne 's#PAT.*//(.*)\n##; $k=$1; $k=~s#[./]##g;open($F,">","$k.txt"); 
              s/\n\s*(\n|$)//g; print $F "$_\n"' original.txt 

На Вашем примере, который привел бы к следующим файлам:

askubuntucompage01.txt
askubuntucompage02.txt
askubuntucompage03.txt
3
ответ дан 1 December 2019 в 13:16

Другие вопросы по тегам:

Похожие вопросы: