コードジェネレータの出力をクリーンアップしようとしています。残念ながら、複数のインポートが生成されます。
import Foo
...
import Foo
幸いにも、生成されたテキストは頻繁に再生成されますが、比較的静的であるため、簡単に削除する方法があることを願っています。
私は彼らが同じ行にいる場合は、次のことができることがわかりました。sed 's/import Foo//2g'
しかし、私はすべての行を考慮するためにsedについて十分に知りません。
ハッキーソリューションは複数のsedを実行することです。
sed 's/\n/<string I know doesn't appear>/g'
sed 's/import Foo//2g'
sed 's/<string I know doesn't appear>/\n'
しかし、そうするのは間違っているようです。もっと良い方法がありますか?
答え1
sed '/^import Foo$/{x;/^$/!d;g;}'
仕組み:パターンに一致するすべての行で
x
:予約済みスペースに行を交換します。/^$/!d
:保存スペースで得たコンテンツが空でない場合です。前の一致がそこに保存されているので、パターンを削除して次の行に進みます。g
:そうでない場合(つまり、最初のパス)、保存された行を再コピーします。デフォルトでは印刷されます。
答え2
GNU実装sed
(すでにGNUismを使用しているため、おそらく使用されているでしょう2g
)を使用して次のことができます。
sed '0,/import Foo/!{//d}' < file
import Foo
最初の行を除くすべての行が削除されます。/^import Foo$/
次の基準に一致する行のみを削除するには、パターンを次に置き換えます。正確に import Foo
。
ここでも使用できますawk
。
awk '!/import Foo/ || !n++' < file
答え3
あなたのsed
バージョンで許可されている場合は試してみてください。
sed -z 's/import Foo//2g' file
答え4
シンプルで移植可能な状態に保ち、awkを使用する必要があります。
$ cat file
import Foo
import Bar
import More
import Foo
import Stuff
import Bar
$ awk '!seen[$0]++' file
import Foo
import Bar
import More
import Stuff
または、一意にしたい行で始まり、import
入力に触れたくない他の行がある場合:
$ cat file
import Foo
int 3;
import Bar
char 7;
import More
int 3;
import Foo
char 7;
import Stuff
whatever
import Bar
whatever
$ awk '!(/^import/ && seen[$0]++)' file
import Foo
int 3;
import Bar
char 7;
import More
int 3;
char 7;
import Stuff
whatever
whatever