【问题标题】:Mass regex search-and-replace BETWEEN patterns大规模正则表达式搜索和替换模式之间
【发布时间】:2018-11-21 17:55:31
【问题描述】:

我有一个包含一堆文本文件的目录,所有文件都遵循以下结构:

...
 - Some random number of list items of random text
 - And even more of it

PATTERN_A (surrounded by empty lines)

 - Again, some list items of random text
 - Which does look similar as the first batch

PATTERN_B (surrounded by empty lines)

 - And even more some random text
....

并且我需要仅对位于 PATTERN_A 和 PATTERN_B 之间的那些“列表项”运行替换操作(比如说,我需要在行首添加 CCC,就在破折号之后)。问题是它们与 PATTERN_A 上方或 PATTERN_B 下方的文本并没有太大区别,因此普通的正则表达式无法真正捕获它们而不影响其余文本。

那么,我的问题是,我应该使用什么工具和什么正则表达式来执行替换?

(以防万一,我对 Vim 没问题,例如,我可以在 QuickFix 中收集这些文件以进一步获取 :cdo。不幸的是,我对 awk 不是很好,对 Perl 绝对不好:))

谢谢!

【问题讨论】:

  • 您可以发布示例输出吗?

标签: regex shell


【解决方案1】:

如果我理解了您的问题,您可以通过模式范围选择和sed(流编辑器)的一般替换形式轻松做到这一点。例如,在您的情况下:

$ sed '/PATTERN_A/,/PATTERN_B/s/^\([ ]*-\)/\1CCC/' file
 - Some random number of list items of random text
 - And even more of it

PATTERN_A (surrounded by empty lines)

 -CCC Again, some list items of random text
 -CCC Which does look similar as the first batch

PATTERN_B (surrounded by empty lines)

 - And even more some random text

注意:要在文件中就地替换,请添加-i 选项,并创建原始文件的备份添加-i.bak,这会将原始文件保存为file.bak

说明

  • /PATTERN_A/,/PATTERN_B/ - 在 PATTERN_APATTERN_B 之间选择行
  • s/^\([ ]*-\)/\1CCC/ - 替换(一般形式's/find/replace/'),其中find 是从行首^ 捕获包含\(...\) 之间的文本,其中包含[ ]*-(任意数量的空格和连字符),然后是replace \1(称为反向引用,包含您使用捕获组\(...\) 捕获的所有字符)并在其末尾附加CCC

如果您有任何问题或我误解了您的问题,请查看并告诉我。

【讨论】:

  • 谢谢,大卫!与您同时,我刚刚记得 Vim 实际上允许完全相同的事情,通过指示搜索模式来选择范围,例如 :/PATTERN_A/, /PATTERN_B/s/\(^ \+-\)/\1 CCC/。给您添麻烦了!
  • 是的,vim 也允许正则表达式替换。如果您的文件有可能以tab 字符开头,而不仅仅是'-' 之前的spaces,您可以将文字零个或多个空格[ ]* 字符更改为零个或多个空格改用\s*
【解决方案2】:

使用 Perl 也可以得到结果

> perl -pe ' { s/^(\s*-)/\1CCC/g if /PATTERN_A/../PATTERN_B/ } ' mass_replace.txt
...
 - Some random number of list items of random text
 - And even more of it

PATTERN_A (surrounded by empty lines)

 -CCC Again, some list items of random text
 -CCC Which does look similar as the first batch

PATTERN_B (surrounded by empty lines)

 - And even more some random text
....
> 

【讨论】:

  • 谢谢,这看起来很可读,实际上:)(喜欢if的用法,以后会尝试使用类似的东西)
猜你喜欢
  • 1970-01-01
  • 2010-11-19
  • 2013-06-14
  • 1970-01-01
  • 2018-05-25
  • 2010-11-25
  • 2010-10-30
  • 1970-01-01
相关资源
最近更新 更多