Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/shell/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
模式之间的Mass regex搜索和替换_Regex_Shell - Fatal编程技术网

模式之间的Mass regex搜索和替换

模式之间的Mass regex搜索和替换,regex,shell,Regex,Shell,我有一个包含大量文本文件的目录,所有这些文件都遵循以下结构: ... - 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 (su

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

...
 - 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
....
我只需要在模式a和模式B之间的“列表项”上运行替换操作(比方说,我需要在行首,破折号之后预先添加CCC)。问题是它们与模式a上方或模式B下方的文本没有太大区别,因此,一个普通的正则表达式不能在不影响其余文本的情况下真正捕获它们

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

(以防万一,我对Vim没什么问题,我可以在一个快速修复程序中收集这些文件,以便进行进一步的
:cdo
,例如。不幸的是,我对awk不太在行,对Perl也绝对不在行:)


谢谢

如果我已经理解了您的问题,您可以通过模式范围选择和使用
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
选项,并创建原始add
-i.bak
的备份,该备份将原始文件另存为
file.bak

解释

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

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

如果我理解了您的问题,您可以通过模式范围选择和使用
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
选项,并创建原始add
-i.bak
的备份,该备份将原始文件另存为
file.bak

解释

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

如果您有问题或我误解了您的问题,请仔细检查并告诉我。

使用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
....
> 

使用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
....
> 

您可以发布示例输出吗?您可以发布示例输出吗?谢谢,David!同时,我还记得Vim实际上允许完全相同的事情,通过指示搜索模式来选择范围,如下面的
:/PATTERN\u a/,/PATTERN\u B/s/\(^\+-\)/\1 CCC/
。很抱歉给您添麻烦!是的,vim也允许正则表达式替换。如果您的文件可能以
选项卡
字符开头,而不仅仅是
空格
'-'
之前,您可以更改文本零或更多空格
[]*
使用
\s*
将字符设置为零或更多的空格。谢谢,David!同时,我还记得Vim实际上允许完全相同的事情,通过指示搜索模式选择一个范围,如下面的
:/PATTERN\u a/,/PATTERN\u B/s/\(^\+-\)/\1 CCC/
。很抱歉给您添麻烦!是的,vim也允许正则表达式替换。如果您的文件可能以
选项卡
字符开头,而不仅仅是
空格
'-'
之前,您可以更改文本零或更多空格
[]*使用
\s*
改为使用
\s*
将字符转换为零或更多的空白。谢谢,这看起来非常可读,实际上:)(喜欢
if
的用法,将来会尝试使用类似的用法)谢谢,这看起来非常可读,实际上:)(喜欢
if
的用法,将来会尝试使用类似的用法)