按页读取数据并存储在单独的文件中

按页读取数据并存储在单独的文件中

我有一个巨大的文本文件,其中数据按页分隔。例如,文本采用以下格式,我想按页读取行并将每个页面存储在单独的文件中。

Page 1
 line 1
 line 2
 line 3
 line 4
 line 5
Page 2
 line 1
 line 2
 line 3
 line 4
 line 5
Page 3
 line 1
 line 2
 line 3
 line 4
 line 5

答案1

解决方案:

awk '/^Page [0-9]+$/ {N = $2}; {print > "page"N}' pages

测试运行:

==> page1 <==
 line 1
 line 2
 line 3
 line 4
 line 5

==> page2 <==
 line 1
 line 2
 line 3
 line 4
 line 5

==> page3 <==
 line 1
 line 2
 line 3
 line 4
 line 5

但是,如果有数千个页面,则在某些awk实现中,您可能会遇到打开文件数量的限制。您可以通过在找到新页眉时关闭上一页的文件来解决这个问题。您可能还需要用 0 填充文件名中的数字,以便ls按升序显示它们:

awk '
  /^Page [0-9]+$/ {close(file); file = sprintf("page%04d", $2)}
  {print > file}' pages

假设输入每页仅包含一次 。Page n

答案2

另一种解决方案,它不像原来的解决方案那么优雅awk,因为它需要:

  • 知道每页的行数
  • 这个数字必须在所有页面上保持不变

    split -l 6 -a 2 -d input page_
    

这里,6是每页的行数:1个标题行+5个数据行

答案3

使用csplit

$ csplit -s -f page- file '/^Page/' '{1}'
$ ls
file    page-00 page-01 page-02
$ cat page-00
Page 2
 line 1
 line 2
 line 3
 line 4
 line 5
$ cat page-01
Page 2
 line 1
 line 2
 line 3
 line 4
 line 5
$ cat page-02
Page 3
 line 1
 line 2
 line 3
 line 4
 line 5

csplit实用程序根据给定文件的最后一个参数分割给定文件。此处,/^Page/and{1}指示csplit每次匹配时根据给定的正则表达式分割文件。对于 GNU csplit,您可能希望使用{*}而不是{1}(上面的示例是为 OpenBSD 编写的csplit)。

答案4

命令:

awk '$0 ~/Page 1/{f=1}$0 ~/Page 2/{f=0}f' o.txt > firstfile
 awk '$0 ~/Page 2/{f=1}$0 ~/Page 3/{f=0}f' o.txt > secondfile
awk '/Page 3/,/,/{print $0}' o.txt >thirdfile

输出

een@praveen:~$ awk '$0 ~/Page 1/{f=1}$0 ~/Page 2/{f=0}f' o.txt > firstfile
Page 1
 line 1
 line 2
 line 3
 line 4
 line 5
praveen@praveen:~$ awk '$0 ~/Page 2/{f=1}$0 ~/Page 3/{f=0}f' o.txt > secondfile
Page 2
 line 1
 line 2
 line 3
 line 4
 line 5



awk '/Page 3/,/,/{print $0}' o.txt >thirdfile
Page 3
 line 1
 line 2
 line 3
 line 4
 line 5
praveen@praveen:

〜$

相关内容