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)在其内部(而不是外部)
文件中可能有几个开始和结束模式;我想修改所有实例。某些实例可能位于同一行上
我更喜欢GNUsed
而不是GNUawk
(因为我使用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,GNUsed
中不存在负回溯这类事情;您知道另一种处理方法吗?另一个问题是,如果我对文件使用以下命令,它会用奇怪的输出替换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