Awk 模式1和第一个模式2之间的双引号匹配,并替换文件中的换行符(输出整个文件) 问题定义

Awk 模式1和第一个模式2之间的双引号匹配,并替换文件中的换行符(输出整个文件) 问题定义,awk,sed,Awk,Sed,我想从一个文件(或STDIN)中捕获一个多行子字符串,将其双引号并替换所有换行符(\n→ \\n)在其内部(而不是外部) 文件中可能有几个开始和结束模式;我想修改所有实例。某些实例可能位于同一行上 我更喜欢GNUsed而不是GNUawk(因为我使用sed多于awk,但是,在解决方案中使用哪一个并不重要,只要让它在Linux上的Bash中工作即可 匹配子字符串的示例 date:await(异步(y:number):Promise=>{ const firstDayOfOT=dayjs((等待季节。

我想从一个文件(或
STDIN
)中捕获一个多行子字符串,将其双引号并替换所有换行符(
\n
→ <代码>\\n)在其内部(而不是外部)

文件中可能有几个开始和结束模式;我想修改所有实例。某些实例可能位于同一行上

我更喜欢GNU
sed
而不是GNU
awk
(因为我使用
sed
多于
awk
,但是,在解决方案中使用哪一个并不重要,只要让它在Linux上的Bash中工作即可

匹配子字符串的示例
date:await(异步(y:number):Promise=>{
const firstDayOfOT=dayjs((等待季节。earlyOrdinaryTime(y,config.epiphanyOnSunday))[0]。日期);
返回firstDayOfOT.add(2,'周').startOf('周');
})(年),
我试过的 我尝试了以下命令,但
sed
是贪婪的,即它匹配最后一个结束匹配,因此在有多个实例时不起作用。还要注意,此命令仅对捕获的匹配进行双引号引用;它不替换换行符

sed-n'1h;1!H;${g;s/date:\(wait.*[(]year[)]\)/date:“\1”/p}”文件
加分 虽然我在上面提到了一个单一的开始/结束模式对,但实际上有三个(加上其中一个的两个单行变化),见下文。注意,我已经删除了缩进(实际上这并不重要,因为它可以通过
^\s*
轻松批处理)

如果你愿意帮助我,你也可以包括这些模式

date:((y:number):dayjs.dayjs=>{
const date=dayjs.utc(`${y}-11-1`);
如果(日期()==6){
返回dayjs.utc(`y}-11-2`);
}否则{
返回日期;
}
})(年),
date:await(异步(y:number):Promise=>{
const firstDayOfOT=dayjs((等待季节。早期或日常时间),
config.epiphanyonsday))[0]。日期);
返回firstDayOfOT.add(2,'周').startOf('周');
})(年)
date:(():dayjs.dayjs=>{
const firstDay=dayjs.utc(`${year}-1-1`);
const feastDay=22-(firstDay.day()=0?7:firstDay.day());
return dayjs.utc(`year}-1-${feastDay}`);
})(),
//一行程序
日期:((y:number):Dayjs=>Dates.pentecostSunday(y).add(1,'day'))(年),
日期:((y:number):dayjs.dayjs=>Dates.pentecostSunday(y).add(1,'day'))(年),
为什么我需要这个? 我想从中解析日历文件(除了
index.ts
test.ts
)我希望
jq
可以解析TypeScript对象(或任何它们被调用的对象),但因为它不能做到这一点,我想用它“转换”成一个正确的JSON字符串,然后用
jq
解析它

现在,为了通过
hjson
使文件“可转换”,我需要执行以下操作:

  • 删除
    const\u dates:Array上面的行(包括)
  • 删除
    下面的行,获取本地化的礼拜日名称
    (包括)
  • 格式化数组:
    • hjson
      不喜欢与数组项位于同一行的方括号(它们必须位于单独的行上)
    • 每个数组项必须位于单独的行上
    • 如果不加引号,则每个数组项后面不能跟逗号,否则该逗号将成为数组项的一部分
  • 除非用
    \\n
    替换换行符,否则任何值都不能是多行值
  • 如果包含特殊字符(由TS/JS解释,例如
    {}[]
    、反勾号甚至逗号),则必须引用该值
除了最后两个,我已经完成了。请参阅以下命令(
general.ts
来自)。请注意,我确信这可以得到优化和完善

sed'1,/const\u dates:Array=\[/d;/Get localized礼拜日名称/,$d'general.ts|\
sed-z的/^/[\n/;s/\];/]\
s/\([^\n]\)\(标题[^\n]*\),*/\1\n\2/g\
s/\(标题。[^,\n]*\),*\s*\]/\1\n]/g\
s/\([^\n]\)\(礼拜仪式颜色。[^,\n]*\),*/\1\n\2/g\
s/\(礼仪色彩。[^,\n]*\),*\s*\]/\1\n]/g\
s/\(cycles:{\)\(celebrationCycle:CelebrationsCycle.TEMPORALE\)\(}\)/\1\n\2\n\3/g'\
sed-n'1h;1!H;${g;s/日期:\(wait.*[(]年[)]\)/日期:“\1”/p}”;小于
这可能适合您(GNU-sed):

收集以日期开始的行:
和等待的行(
)、
((y:number):
(():
)以及以年份结束的行(
)加上或不加上
。然后将所有
\n
替换为
\\n
,并用双引号将集合括起来


这可能需要一些调整来满足您的所有要求。

谢谢,@poton!它工作得很好,但是,它将
日期:
放在双引号中,但这不是值的一部分(它是键名)。无论如何,我想我们可以取消检查开始模式(除了
日期:
),因为我认为所有的
date
键值都应该被引用。结束模式可以简化为
([year]*)|`)
(尾随逗号不是值的一部分,因此不应该被引用)。→
sed'/^date:/{:a;/\([year]*)\\\\\\\`a)\?$/!{N;ba};s/\N/\\N/g;s/*/“&”/}'
AFAIK,GNU
sed
中不存在负回溯这类事情;您知道另一种处理方法吗?另一个问题是,如果我对文件使用以下命令,它会用奇怪的输出替换
date
元素(它以某种方式合并了多个
date
元素值或什么)。命令:
sed'1,/const\u dates:Array=\[/d;/Get localized礼拜日名称/,$d'general.ts | sed'/^\s*date:/{:a;/\([year]*)\\\\\\([year]*)\\\\\\/!{N;ba};s/\N/\\\N/g;s/*“&/”&///}less
sed '/^date: \(await\|((y: number):\|(():\)/{
      :a;/\((year)\|()\),\?$/!{N;ba};s/\n/\\n/g;s/.*/"&"/}' file