2016-09-19 6 views
2

前に挿入する#include をsedは、私は下記のようないくつかのソースは、file1.cppに似たファイルを持っている: のSolaris 10、Solaris 10で最初の#include文の

// 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$$ 

しかし、これは私の要件ごとに動作しない、提案してください。

+0

これを行うプログラムや、linuxコマンドを探すプログラムを書こうとしていますか?それが後者なら、どこかに一般的なLinuxの回答があるはずだから、それが本当に適切だとは思わない。 – NathanOliver

+0

@NathanOliver上記のようなさまざまなシナリオを処理するbashシェルスクリプト –

+0

@NathanOliver Linuxをどこから取得しているのかわかりません。 Solaris 10について具体的に質問しています。 –

答えて

2

これはLinuxでも問題なく動作しますが、Solarisで動作するはずです。

ファイルxyz.c

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

the real code 

コマンド:あなたが最初の行の先頭に#includeを持つファイルに対処する必要がある場合は

$ 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 
$ 

、それがfiddlierです。変更なしでは、#include <iostream>が1行目の前に挿入されています(必要なもの)。また、1行目の後の最初の行の前には、#includeで始まります。 GNU sedでは、1の代わりに0を使用することができます。ライン0を参照することはPOSIXの標準機能ではなく、おそらくSolarisでは動作しません。

私はそれなしで最適な回避策だかわからないんだけど - たぶんawkを使用して代わりにsedすることはもちろん、少なくとも難しい(と、それは最初の行の後に最初の#includeのためにうまく動作と同様である - それはより一般的です溶液):私は、以前のスクリプトで設定NM=iostreamすなわち、$NMで捕獲変数としてiostreamを持つようにしたいどのような程度であれば

awk '/^[:space:]*#[:space:]*include/ { if (done++ == 0) 
              print "#include <iostream>" } 
    {print}' …filename… 

awkの中で$NMを使用するにはどうすればよいですか?

NM="iostream" 

awk -v header="$NM" \ 
    '/^[:space:]*#[:space:]*include/ { if (done++ == 0) 
              printf "#include <%s>\n", header } 
    {print}' …filename… 

キーポイントはawkスクリプトにヘッダ名を中継するコマンドライン上の-v variable=valueの使用であり、次いで(改行であることを覚えて正しく文字列をフォーマットするprintfprintを変更します必要)。

+0

awkの使い方はいいですね、もしiostreamを$ NMでキャプチャされた変数、つまりNM = iostreamをスクリプトの前の方に設定したいのであれば、どうしたらawkの$ NMをawkの/^[:space :] *#[:space:] * include/{if(done ++ == 0) "#include "} {print} '...ファイル名... –

関連する問題