Solaris 10,sed在#include语句

时间:2016-09-19 17:14:47

标签: bash awk sed solaris-10

在Solaris 10上,我有几个类似于file1.cpp的源文件,如下所示:

// file1.cpp
#include <string>
#include <unordered_map>
void func() {
. . .
}

我想在第一个#include <iostream>之前插入#include(如果有的话):因此,该文件将成为:

// file1.cpp
#include <iostream>
#include <string>
#include <unordered_map>
void func() {
. . .
}

如果没有包括例如

// file1.cpp
void func() {
. . .
}

这将成为:

// file1.cpp
#include <iostream>
void func() {
. . .
}

但是,如果文件已包含#include <iostream>,则会忽略另一个#include <iostream>的插入。因此,如果我们有,

// file1.cpp
#include <string>
#include <unordered_map>
#include <iostream>
void func() {
. . .
}

它将保持不变,即

// file1.cpp
#include <string>
#include <unordered_map>
#include <iostream>
void func() {
. . .
}

我的尝试:

bash-3.00$ cat TRYIT
#!/bin/bash
echo \#include \<iostream\> > x$$
for  i in `find . -type f -name "*.cpp"`
do
 if  ! grep -s "\#include \<iostream\>" "$i"  > /dev/null; then
    sed  "/\#include/r x$$" "$i" > "$i".bak
    mv "$i".bak "$i"
 fi
done
rm x$$

但是根据我的要求,这不起作用,请建议。

1 个答案:

答案 0 :(得分:2)

这在Linux上运行正常,我相信它应该适用于Solaris。

档案xyz.c

/* First line must not start #include */
#include <stdio.h>
#define PERGATORY
#include <meniscus.h>

the real code

命令:

$ sed -e '1,/^[:space:]*#[:space:]*include/ { /^[:space:]*#[:space:]*include/i\
> #include <iostream>
> }' xyz.c
/* First line must not start #include */
#include <iostream>
#include <stdio.h>
#define PERGATORY
#include <meniscus.h>

the real code
$

如果你需要处理在第一行开头有#include的文件,那就更加狡猾了。如果没有更改,您会在第1行(想要的内容)之前插入#include <iostream>,也可以在以#include开头的第1行之后的第一行之前插入sed。使用GNU 0,您可以使用1代替awk并且效果很好;引用第0行不是POSIX标准功能,但可能不适用于Solaris。

我不确定没有它的最佳解决方法是什么 - 可能使用sed代替#include是最难的(并且它适用于第一行之后的第一个awk '/^[:space:]*#[:space:]*include/ { if (done++ == 0) print "#include <iostream>" } {print}' …filename… 当然,这也是一个更通用的解决方案):

iostream
  

如果我希望将$NM作为NM=iostream中捕获的变量,即脚本中先前设置的$NM怎么办?如何在awk中使用NM="iostream" awk -v header="$NM" \ '/^[:space:]*#[:space:]*include/ { if (done++ == 0) printf "#include <%s>\n", header } {print}' …filename…

-v variable=value

关键是在命令行上使用awk将标头名称转发到print脚本,然后将printf修改为find_host(...)到正确格式化字符串(记住需要换行符)。