我想将一个文本文件拆分成几个。每次出现模式时都会生成一个新文件。示例:模式将是 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 等命令... 重命名文件是次要的,但有助于对文件进行分类。提前致谢。
答案1
您可以使用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"
在创建“大量”文件时出现错误。
答案2
由于@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
,我们使用文件句柄 来$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
另请查看 csplit(1):
csplit --suppress-matched --prefix page --suffix-format %02d.txt original.txt '/^PAT/' '{*}'
分割文件原文.txt当发现正则表达式模式时,将其分成单独的文件。
page00.txt
page01.txt
...