最初のパターンを除くすべてのパターンを削除します。

最初のパターンを除くすべてのパターンを削除します。

コードジェネレータの出力をクリーンアップしようとしています。残念ながら、複数のインポートが生成されます。

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

関連情報