2016-06-13 114 views
0

我有一個工具可以生成一些源代碼。不幸的是,該工具從源代碼中跳過使用子句。最後一次出現匹配行後追加文本

使用像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(); 

回答

3

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

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

0

這可能爲你工作(GNU SED):

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

啜食文件到內存中,並用貪婪找到所需的字符串中的最後一行,然後插入所需的字符串。

0

將問題分解成簡單的步驟:找到包含#include的行,找到這些行的最後一行,在該行附加額外的行。

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

這將設置在bash變量lno到最後行號(由打印的sed =)。 最後一個sed在該行之後追加一個空行和您的行,編輯原地文件。

相關問題