使用 Linux 命令行,当出现模式时将文本文件拆分为多个

使用 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 等命令... 重命名文件是次要的,但有助于对文件进行分类。提前致谢。

答案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;删除空行,最后,使用 将当前记录打印到文件句柄$Fprint $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
...

相关内容