最后一次出现匹配行后追加文本

问题描述:

我有一个工具可以生成一些源代码。不幸的是,该工具从源代码中跳过使用子句。最后一次出现匹配行后追加文本

使用像sed实用,我怎么插入到一个源文件这样的行

using namespace xyz; 

出现一次和最后一行后包含的#include?

例如

#include <string.h> 
#include <stdio.h> 


// some functions 
void blabla(); 

将成为:

#include <string.h> 
#include <stdio.h> 

using namespace xyz; 

// some functions 
void blabla(); 

sed的是个人行简单的换人,这是所有。为别的,你应该使用AWK:以上

$ awk 'NR==FNR{if (/#include/) nr=NR; next} {print; if(nr==FNR) print "\nusing namespace xyz;"}' file file 
#include <string.h> 
#include <stdio.h> 

using namespace xyz; 


// some functions 
void blabla(); 

使用2次 - 第一个发现那里的#include最后一次出现在文件中出现的行号并将其存储在一个名为nr变线号然后第二个打印“使用...”,当该行号在该第二遍中被打上时。如果您希望复制参数列表数组中的文件名,则可以通过将awk 'script' file file更改为awk 'BEGIN{ARGV[ARGC]=ARGV[1]; ARGC++} script' file而不指定文件名两次来执行此操作。

或者,如果文件不是很大,则可以将其全部读入内存,然后进行替换,将整个文件视为单个字符串,例如,与GNU AWK多炭RS和gensub():

$ awk -vRS='^$' -voORS= '{print gensub(/(.*#include[^\n]+\n)/,"\\1\nusing namespace xyz;\n",1)}' file 
#include <string.h> 
#include <stdio.h> 

using namespace xyz; 


// some functions 
void blabla(); 

与其他awks你会通过线串行建立到一个变量然后,在端部使用匹配()和SUBSTR处理( ):

$ awk -v ORS= '{rec = rec $0 RS} END{ if (match(rec,/.*#include[^\n]+\n/)) rec = substr(rec,1,RSTART+RLENGTH-1) "\nusing namespace xyz;\n" substr(rec,RSTART+RLENGTH); print rec}' file 
#include <string.h> 
#include <stdio.h> 

using namespace xyz; 


// some functions 
void blabla(); 
+0

这似乎并不奏效。没有输出产生。我正在使用gawk 4.0.1 – Matt

+0

啊,我必须把文件放两次?这是为什么? – Matt

+1

我在答案中添加了解释。 –

这可能为你工作(GNU SED):

sed '1h;1!H;$!d;x;/.*#include[^\n]*\n/s//&\ninsert a line here\n/' file 

啜食文件到内存中,并用贪婪找到所需的字符串中的最后一行,然后插入所需的字符串。

将问题分解成简单的步骤:找到包含#include的行,找到这些行的最后一行,在该行附加额外的行。

lno=$(sed <file -n '/^#include/=' | sed -n '$p') 
sed -i file -e "$lno"'a\ 
\ 
using namespace xyz; 
' 

这将设置在bash变量lno到最后行号(由打印的sed =)。 最后一个sed在该行之后追加一个空行和您的行,编辑原地文件。