特定の行の周りのパターンを削除する必要があります:
#undef LZZ_INLINE
#ifdef LZZ_ENABLE_INLINE
#include "somename.inl"
#endif
次のようになる必要があります。
#include "somename.inl"
somename
前もってわかりません。これは、一般的な方法で sed や awk などを使用してどのように行うことができますか?
ファイルサイズが一度にメモリに読み込むことができる場合は、次のことができます
sed -i.bk ':a;$!{N;ba}; s/#undef LZZ_INLINE\n#ifdef LZZ_ENABLE_INLINE\n\(#include [^\n]*\)\n#endif/\1/g' input.file
.bk
すべてがうまくいけば、ファイルを削除してください:)
@glennjackmanが投稿した答えを仮定すると:
awk '/#undef LZZ_INLINE/{next} /#ifdef LZZ_ENABLE_INLINE/{x=1;next}x&&/#endif/{x=0;next} 1' file
入力ファイルをインプレースで更新したい場合は、awk を使用してこれを行う 1 つの方法を次に示します。
awk '/#undef LZZ_INLINE/{next} /#ifdef LZZ_ENABLE_INLINE/{x=1;next}x&&/#endif/{x=0;next} {out[++nr]=$0} END{close(FILENAME); for (i=1;i<=nr;i++) print out > FILENAME}' file
(つまり に置き換え1
ます{out[++nr]=$0} END{close(FILENAME); for (i=1;i<=nr;i++) print out > FILENAME}
)
ここに別のものがあります:
awk '/#undef LZZ_INLINE/{next} /#ifdef LZZ_ENABLE_INLINE/{x=1;next}x&&/#endif/{x=0;next} {print > "/tmp/\""FILENAME"\"" } END{system("mv /tmp/\""FILENAME"\" \""FILENAME"\""}' file
(つまり に置き換え1
ます{print > "/tmp/\""FILENAME"\"" } END{system("mv /tmp/\""FILENAME"\" \""FILENAME"\""}
)
実装方法にはいくつかのバリエーションがありますが、基本的な考え方は、入力ファイルの読み取りが完了するまで出力をバッファリングしてから、入力ファイルを上書きすることです。いずれにせよNBD...
言及する必要があるもう 1 つのバリエーションは、次のような tmp INPUT ファイルを作成することです。
awk '
BEGIN{
tmp="/tmp/\"" ARGV[1] "\""
while ( (getline var < ARGV[1]) > 0 ) {
print var > tmp
}
close(tmp)
out = ARGV[1]
ARGV[1] = tmp
}
/#undef LZZ_INLINE/{next} /#ifdef LZZ_ENABLE_INLINE/{x=1;next}x&&/#endif/{x=0;next} {print > out}' file
system("mv...") を使用するか getline ループを使用するかは、スタイルまたは OS が提供するものに依存します。
このワンライナーがあなたのために働くかどうか試してください:
awk '/#undef LZZ_INLINE/{next;} /#ifdef LZZ_ENABLE_INLINE/{x=1;next;}x&&/#endif/{x=0;next;}1' file
これを fix.sed というファイルに追加します
/^#undef LZZ_INLINE/{
N
N
N
s/.*\(#include "[^"]*"\).*/\1/
}
次のように実行します。
sed -f fix.sed 元のファイル