我正在尝试修改几个文件中的几行块。最初,我尝试了 sed,但读到 Perl 可能是更好的选择。但是,我的 Perl 非常基础,我不确定如何处理空(新)行和特殊字符“/”。总而言之,我想要一个像 ( $perl -i -pe ...
) 这样的单线来转换
(new line)
#include <item_b/item_bC.h>
进入
#include <item_a/item_aC.h>
#include <item_b/item_bC.h>
谢谢。
一种方法 - 将文件放入字符串中,然后匹配仅可能有空格的行,后跟以 开头的行#include...
,并替换与该#include
行匹配的内容两次
perl -0777 -wpe's{ ^\s*\n ( \#include.*\n ) }{$1$1}mxg' file.c
与-0777
它吸食整个文件到$_
与-p
它打印$_
一个每一行(一旦当用于-0777
自HTE整个文件是在$_
这样有一个这样的“线”); 请参阅perlrun 中的开关。所述/m
改性剂品牌^
(和$
)也是一个(多)字符串内匹配线边界。
或者,以相同的一般方法(吞咽文件)但使用前瞻
perl -0777 -wpe's{ ^\s*\n (?= (\#include.*\n) ) }{$1}mxg' file.c
匹配一个空行,然后先行查找以 开头的行#include
,该行也被捕获,以便用它替换空行。由于环视不消耗任何东西,因此无需替换该行(用它自己)。
请注意,这.*
是贪婪的并且尽可能多地匹配它.*\n
后面的模式,这里我们在它前面有整个文件,所以它可能看起来会一直匹配到\n
文件中的最后一个!但是,.
不匹配换行符(带有/s
修饰符),因此.*\n
此处在第一个换行符处停止,因此它与该行的其余部分匹配。
如果需要匹配更具体的包含语句,请按照#include
模式添加详细信息。†
否则,可以逐行处理,通过复制当前行并在下一行打印,具体取决于保存的和下一行的内容。那里有一些挑剔的细节需要整理,而不是超级适合单线。
都用输入测试 file.c
#include<item_b/item_bC.h> #include<item_a/item_aC.h> #include<item_c/item_cC.h> int main() { return 1; }
我们最终得到两个item_b
、一个item_a
和两个itewm_c
包含且没有空行,文件的其余部分不受影响。
†提到了特殊字符,所以我会发表评论。但请参考更完整的资源,如教程perlretut和参考perlre。另见perlrebackslash
正则表达式的特殊字符在使用\
. 但在这种情况下,这不是必需的:/
在正则表达式中的作用只是分隔模式,通常以 给出/.../
,但在这里我{}{}
用作分隔符;所以/
这里没什么特别的,可以自由使用。例如
perl -0777 -wpe's{ ^\s*\n (?= (\#include<item_./.*\n) ) }{$1}mxg' file.c
匹配我使用的输入文件中的行,如上所示。
显然有一个更通用的模式而不是item
实际问题,它是一个文件名。文件名中允许的大多数字符都可以在正则表达式中直接使用。例外,比如.
,可以被转义,比如\.
匹配一个文字.
。
例如,一个字符串item_bC.h
,其中bC
的字符而变化,但是item
与.h
总是相同的,可以用模式匹配/item_..\.h/
。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句