Я хочу разделить текстовый файл на несколько. Один новый файл каждый раз шаблон появляется. Пример: шаблоном будет 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... Переименование файлов вторично, но было бы плюс помочь классификации их.Заранее спасибо.
Вы могли использовать 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"
ошибка, когда существует "много" созданного файла.
Также взгляните на csplit (1):
csplit --suppress-matched --prefix page --suffix-format %02d.txt original.txt '/^PAT/' '{*}'
файл Разделений orginal.txt в отдельные файлы, когда regex шаблон найден.
page00.txt
page01.txt
...
Так как @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