首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >pattern1和第一个pattern2之间的双引号匹配,并在文件中替换换行符(输出整个文件)

pattern1和第一个pattern2之间的双引号匹配,并在文件中替换换行符(输出整个文件)
EN

Stack Overflow用户
提问于 2020-10-02 14:34:17
回答 1查看 48关注 0票数 0

问题定义

我想从一个文件(或STDIN)中捕获一个多行子字符串,双引号并替换其中的所有换行符(\n\\n) (而不是在其中)。

文件中可能有几种开始和结束模式;我想修改所有的实例。有些实例可能位于单行。

我更喜欢GNU sed而不是GNU awk (仅仅因为我使用sed而不是awk,但是,在解决方案中使用哪一个并不重要,只要让它在Linux上运行就行了。

匹配子字符串的示例

代码语言:javascript
复制
date: await (async (y: number): Promise<Dayjs> => {
  const firstDayOfOT = dayjs((await Seasons.earlyOrdinaryTime(y, config.epiphanyOnSunday))[0].date);
  return firstDayOfOT.add(2, 'week').startOf('week');
})(year),

我试过的

我尝试了以下命令,但是sed是贪婪的,即它匹配最后一个匹配,因此当有多个实例时不能工作。还请注意,此命令仅引用捕获的匹配项;它不替换换行符。

代码语言:javascript
复制
sed -n '1h; 1!H; ${ g; s/date: \(await.*[(]year[)]\)/date: "\1"/p }' file

加分

虽然上面我已经谈到了一个单一的开始/结束模式对,实际上,有三个(加上两个一个线性变化的其中一个),见下文。注意,我已经删除了缩进(它实际上并不重要,因为它可以很容易地由^\s*批处理)。

如果你非常渴望帮助我,你也可以包括这些模式。

代码语言:javascript
复制
date: ((y: number): dayjs.Dayjs => {
  const date = dayjs.utc(`${y}-11-1`);
  if (date.day() === 6) {
    return dayjs.utc(`${y}-11-2`);
  } else {
    return date;
  }
})(year),
代码语言:javascript
复制
date: await (async (y: number): Promise<Dayjs> => {
  const firstDayOfOT = dayjs((await Seasons.earlyOrdinaryTime(y,
    config.epiphanyOnSunday))[0].date);
  return firstDayOfOT.add(2, 'week').startOf('week');
})(year)
代码语言:javascript
复制
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}`);
})(),
代码语言:javascript
复制
// One-liners
date: ((y: number): Dayjs => Dates.pentecostSunday(y).add(1, 'day'))(year),

date: ((y: number): dayjs.Dayjs => Dates.pentecostSunday(y).add(1, 'day'))(year),

为什么我需要这个?

我想解析来自这里的日历文件(除了index.tstest.ts之外的所有这些文件)。我希望jq能够解析TypeScript对象(或者任何被调用的对象),但是由于它不能这样做,所以我希望使用hjson将其“转换”为一个正确的JSON字符串,然后使用jq解析它。

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

  • 删除const _dates: Array<RomcalLiturgicalDayInput>以上的线(包括);
  • 删除Get localized liturgical day names以下的行(包括);
  • 格式数组:
    • hjson不喜欢同一行的方括号与数组项(它们必须在单独的行上);
    • 每个数组项必须位于单独的行上;
    • 如果没有引号,则每个数组项不能后面跟着逗号,否则逗号就会成为数组项的一部分;

  • 除非换行符被\\n替换,否则任何值都不能是多行值;
  • 如果包含特殊字符(由TS/JS解释,例如{}[]、回勾或甚至逗号),则必须引用该值。

除了最后两名,我已经做过了。请参见以下命令(general.ts来自这里)。请注意,我确信这是可以优化和完善的。

代码语言:javascript
复制
sed '1,/const _dates: Array<RomcalLiturgicalDayInput> = \[/d;/Get localized liturgical day names/,$d' general.ts | \
  sed -z 's/^/[\n/;s/\];/]/; \
    s/\([^\n]\)\(Titles.[^, \n]*\),*/\1\n\2/g; \
    s/\(Titles.[^, \n]*\),*\s*\]/\1\n]/g; \
    s/\([^\n]\)\(LiturgicalColors.[^, \n]*\),*/\1\n\2/g; \
    s/\(LiturgicalColors.[^, \n]*\),*\s*\]/\1\n]/g; \
    s/\(cycles: {\) \(celebrationCycle: CelebrationsCycle.TEMPORALE\) \(}\)/\1\n\2\n\3/g' | \
  sed -n '1h; 1!H; ${ g; s/date: \(await.*[(]year[)]\)/date: "\1"/p }' | less
EN

回答 1

Stack Overflow用户

发布于 2020-10-02 15:47:50

这可能对您有用(GNU sed):

代码语言:javascript
复制
sed '/^date: \(await\|((y: number):\|(():\)/{
      :a;/\((year)\|()\),\?$/!{N;ba};s/\n/\\n/g;s/.*/"&"/}' file

收集以date:await((y: number):(():开头的行,以及用或不带,结束(year)()的行。然后将所有\n替换为\\n,并用双引号包围集合。

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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64173385

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档