首页 > 解决方案 > 在第 n 次出现分隔符时拆分文件并将 txt 文件中的内容添加到每个新文件中

问题描述

我想在出现约 5000 次分隔符(在可能的情况下为“00I”)后拆分一个 >500MB 的基于 ASCII 的文本文件。我正在使用来自(https://stackoverflow.com/a/42302328/14957413)的代码

awk -v n=5000 '
   function ofile() {
      if (op) 
         close(op); 
      op = sprintf("file.GES.%d.", ++p)
   } 
   BEGIN{ofile()} 
   /00I/{++i} i>n{i=1; ofile()} 

   { print $0 > op }' 
file

源文件以大约 1000 行变量声明开始,我还需要在使用上面的代码段创建的每个新文件中都有这些声明。

输入

//file header
00K
01Filename
02Fieltype
03Date

//00F describes a variable
00F 
0101
02Variable name 1
03text
04length
00F 
0102
02Variable name 2
03number
04length

//content I want split
00I
01Value for first F, e.g. Test
02Value for second F, e.g. 1
//this repeats a couple of 1.000.000 times
00I
01Value for first F, e.g. TestN
02Value for second F, e.g. N

第一个到第 n 个文件的预期输出

//Header
00K
01Filename
02Fieltype
03Date

//Variable declaration
00F 
0101
02Variable name 1
03text
04length
00F 
0102
02Variable name 2
03number
04length

//Content
00I
01Value for first F, e.g. Test
02Value for second F, e.g. 1

两个想法

  1. 扩展 awk 语句以将源文件的前 1000 行存储在一个变量中,并将其附加到每个新生成的文件中。
  2. 准备一个带有变量声明的单独文件,并将其内容添加到每个新生成的文件中。

问题 完成任务的最佳方法是什么?可以通过扩展 awk 表达式来完成吗?我是否需要运行两个语句 - 第一个是 awk,第二个是 sed 语句?

非常感谢帮助。

标签: awksedsplit

解决方案


使用 GNU awk,您可以执行以下操作:

awk -v n=5000 'BEGIN{RS="\n00I\n"}
               (NR==1){h=$0; next;}
               (i%n==0){close(f); f= "file.GES." (++c); printf "%s",h > f}
               {printf "%s%s", RS, $0 > f; ++i}' file

这将创建包含 5000 条记录的文件。

它是如何工作的?

通过将记录分隔符定义为\n00I\n RS="\n00I\n",我们将输入文件拆分为file一组由 分隔的多行记录 RS。当 awk 处理一条记录时,该记录$0将包含两个\n00I\n. 当 awk 读取第一条记录 ( NR==1) 时,它将把它存储在变量中h。这将包含标题和变量(除非RS在这些块之一中找到)。从那时起,我们开始计算记录。每次我们有 5000 条记录时,我们都会创建一个新文件,其中的名称file.GES.nn每个文件的递增数字。这是在行中完成的

(i%n==0){close(f); f="file.GES." (++c); printf "%s",h > f}

每次处理记录时,我们都会将其打印到文件中并增加i用于检查是否需要新文件的记录计数器。


推荐阅读