最后一次出现匹配行后追加文本
问题描述:
我有一个工具可以生成一些源代码。不幸的是,该工具从源代码中跳过使用子句。最后一次出现匹配行后追加文本
使用像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();
答
这可能为你工作(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
在该行之后追加一个空行和您的行,编辑原地文件。
这似乎并不奏效。没有输出产生。我正在使用gawk 4.0.1 – Matt
啊,我必须把文件放两次?这是为什么? – Matt
我在答案中添加了解释。 –