将文本文件中的块写入多个新文件
Posted
技术标签:
【中文标题】将文本文件中的块写入多个新文件【英文标题】:Write blocks in a text file to multiple new files 【发布时间】:2017-07-14 08:29:16 【问题描述】:我正在尝试提取文本文件中的块并将它们放入新的单个文件中。例如,考虑以下文件:
some junk lines
ABC: this is abc text
abc block text1
abc block text2
abc block text3
I dont care about this line
Text at start of block. I dont want this line also.
ABC: this is another abc text
abc block text5
abc block text2
abc block text3
abc block text1
some other dont care line
我对“ABC”块感兴趣。每个块的开头都有“ABC:”,结尾有新行。所以,我想生成 abc1.txt 包含:
ABC: this is abc text
abc block text1
abc block text2
abc block text3
和 abc2.txt 包含:
ABC: this is another abc text
abc block text5
abc block text2
abc block text3
abc block text1
我尝试使用 awk 获取块,但很难匹配结束新行。
一种选择是编写一个循环遍历文件中每一行的脚本。我相信有更好的解决方案。有人可以帮忙吗?提前致谢!
【问题讨论】:
tried using awk
请将该代码添加到问题中...
【参考方案1】:
这个单线应该可以完成这项工作:
awk '/^ABC/p=1;close(fn);fn="abc"++i!NFp=0pprint > fn' file
以您的示例作为输入:
kent$ awk '/^ABC/p=1;close(fn);fn="abc"++i!NFp=0pprint > fn' f
kent$ head abc*
==> abc1 <==
ABC: this is abc text
abc block text1
abc block text2
abc block text3
==> abc2 <==
ABC: this is another abc text
abc block text5
abc block text2
abc block text3
abc block text1
注意:
close(fn)
是必需的,如果您有许多“ABC”块,否则您会收到诸如“打开的文件过多”之类的错误消息
【讨论】:
非常紧凑的解决方案!即使没有人问,我想我会添加一个更详细的 perl 等效项:perl -lane 'if (/^ABC/) $p=1;$i++;open $f, ">", "abc".$i if (/^$/) $p=0;close $f if ($p==1) print $f $_' test.txt
。
虽然这会产生所需的输出,但它比必要的复杂,因为 awk 具有专门用于处理由空行分隔的数据块的段落模式,请参阅***.com/a/45103787/1745001。【参考方案2】:
您的由空行分隔的文本块的问题正是 awks “段落模式”要处理的问题,并通过将 RS 设置为空字符串来激活:
awk -v RS= '/^ABC:/print > ("abc"++c".txt")' file
如果您没有很多输出文件,或者您使用的是 GNU awk,上述方法将有效,因为它会在必要时为您处理关闭文件。如果您确实有很多输出文件但无法获得 GNU awk,那么您只需将其调整为:
awk -v RS= '/^ABC:/close(f); f="abc"++c".txt"; print > f' file
【讨论】:
【参考方案3】:awk '/^ABC:/,/^$/' filename
搜索所有以 ABC 开头的行:(^ 表示行首)到任何有空行的事物 (^$) 使用 , 来往来行。
【讨论】:
不会将块分隔到不同的文件中以上是关于将文本文件中的块写入多个新文件的主要内容,如果未能解决你的问题,请参考以下文章