【问题标题】:Extracting text between two delimiters in a file and writing to a given filename提取文件中两个分隔符之间的文本并写入给定的文件名
【发布时间】:2018-08-20 17:15:22
【问题描述】:

我希望能够从我的代码中提取 sn-ps 用于文档目的。每次编译代码时我都可以做到这一点,而且成本低廉,这是一种使代码和文档(至少是 sn-ps)保持最新状态的简单方法。

所以我想要一个文件source.cc,里面有这样的东西:

// DOCSNIP: source_def.snip
[code]
// DOCSNIP

显然,一个文件中可能有不止一个。要点是我想分隔一个代码区域(我不喜欢语法),以及一个文件名来粘贴它,并在分隔符之间写入内容(在这种情况下为“[code]”)到一个文件(source_def.snip)。

使用标准工具 (awk/sed/grep) 将这些块提取到各自文件中的最简单方法是什么?

【问题讨论】:

  • 请将该示例输入的所需输出添加到您的问题中。
  • 已经存在但已更新。
  • awk '/DOCSNIP/,/DOCKSNIP/' code.file | head -n -1 > new.txt ; s=$(grep -oP "(?<=DOCSNIP:\s)(.*)" new.txt) ; cat new.txt | tail -n -1 > "$s"

标签: linux shell awk sed grep


【解决方案1】:

awk 来救援!

$ awk '/\/\/ DOCSNIP:/{f=$NF} f{print > f} /\/\/ DOCSNIP$/{f=""}' file

$ head sou*

// DOCSNIP: source_def.snip
[code]
// DOCSNIP

如果文件名中有空格,则无法使用。

如果您不想要分隔线,只需重新排序语句

$ awk '/\/\/ DOCSNIP$/{f=""} f{print > f} /\/\/ DOCSNIP:/{f=$NF}' file

只会打印介于两者之间的内容。

【讨论】:

  • 我知道为什么你被否决了,我们可以从输出中排除分隔符吗?否则这正是我需要的。
  • 这将一直有效,直到您获得大约 20 个输出文件,然后它将开始失败并出现“打开文件过多”错误,除非您使用的是 GNU awk。您应该在任何一个 f=... 分配之前添加一个 close(f) 以便它在所有 awks 中工作,无论输出文件的数量是多少。
【解决方案2】:

使用 AWK

awk '/\/\/ DOCSNIP:/{f=1;print $3;next} /\/\/ DOCSNIP/{f=0} f'
source_def.snip
[code]

这从第一个 DOCSNIP 打印到第二个 DOCSNIP 并输出文件名

【讨论】:

  • 关闭,我想实际提取文件名(source_def.snip)并写入该文件,可能在另一个目录中。
【解决方案3】:

我喜欢 perl,因为它没有不同的风格。也就是说,我认为我更喜欢 awk 。不过,perl 版本(与公认答案的基本思想相同):

perl -ne 'BEGIN{my $fh} {close $fh if /\/\/ DOCSNIP[^:]/; print { $fh } "$_" if $fh!=0; open ($fh, ">>", "$1") or die if /\/\/ DOCSNIP:\s*(.+?)$/; }' main.cc

这支持文件名中的空格,我不认为这是您需要的功能:)

还有一个删除剪辑文件并为您提供预期输出的准备:

 perl -ne 'print if /\/\/ DOCSNIP:/../\/\/ DOCSNIP[^:]/; unlink "$1" if /\/\/ DOCSNIP:\s*(.+?)$/' main.cc

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-02-15
    • 2016-08-02
    • 1970-01-01
    • 2016-01-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多