在 jq 中的另一个匹配行之前添加一个空行?

Add an empty line prior to another matched line in jq?

假设我有如下原始输入:

"```"
"include <stdio.h>"
"..."
"```"
"''some example''"
"*bob"
"**bob"
"*bob"

我想在“*bob”之前添加一个空行:

"```"
"include <stdio.h>"
"..."
"```"
"''some example''"
""
"*bob"
"**bob"
"*bob"

这可以用 jq 完成吗?

是的,但要有效地做到这一点,您实际上需要 jq 1.5 或更高版本:

foreach inputs as $line (0; 
  if $line == "*bob" then . + 1 else . end;
  if . == 1 then "" else empty end,
    $line)

别忘了使用 -n 命令行选项!

这是另一个使用 -s (slurp) 选项的解决方案

.[: .[["*bob"]][0]] + ["\n"] + .[.[["*bob"]][0]:] | .[]        

这有点难以理解,但我们可以通过一些功能使其变得更好:

  def firstbob:  .[["*bob"]][0] ;
  def beforebob: .[: firstbob ] ;
  def afterbob:  .[ firstbob :] ;

    beforebob + ["\n"] + afterbob
  | .[]

如果上面的过滤器在filter.jq并且样本数据在data那么

$ jq -Ms -f filter.jq data

产生

"```"
"include <stdio.h>"
"..."
"```"
"''some example''"
"\n"
"*bob"
"**bob"
"*bob"

此方法的一个问题是,如果 "*bob" 不在输入中,beforebobafterbob 将无法正常工作。解决这个问题的最简单方法是使用 if 保护:

    if firstbob then beforebob + ["\n"] + afterbob else . end
  | .[]

如果 "*bob" 不存在,输入将保持不变。