ファイルから特定の重複行を削除する方法は?

ファイルから特定の重複行を削除する方法は?

複数のファイルから特定の行を削除する方法を探していますが、その行がそのファイルに複数回表示される場合にのみ可能です。他の行は重複しても維持する必要があります。

たとえば、このようなファイルの場合は、重複したファイルを削除したいと思います。AAA

AAA
BBB
AAA
BBB
CCC

しなければならない

AAA
BBB
BBB
CCC

使用する必要があるようですが、sed命令をどのように書くべきかわかりません。

答え1

GNUの使用sed:

sed '0,/^AAA$/b;//d'

つまり、最初の行(行0(最初の行より前でも)と最初の一致行(最初の行にすることができます))まですべてを通過(baのように分岐)し、残りの行からすべての項目を削除します。 (空のパターンは最後のパターンを再利用します)continueAAA/^AAA$/AAA//

sedAddressにはGNUが必要です(同じ式でコマンドの後に他のコマンドを含めることができる0機能もありますが、これは両方の式を使用して異なる実装で簡単に解決できます)。b-e

そしてawk

awk '$0 != "AAA" || !n++'

(または正規表現パターンの場合awk '!/^AAA$/ || !n++':)

略語:

awk '! (&0 == "AAA" && count > 0) {print; count++}'

答え2

Stéphane Chazelasのawkソリューション美しい:

awk '!/AAA/ || !n++' file.in

これは次のように要約できます。

awk '$0 !~ pattern || !n++' pattern="$pattern" file.in

$pattern一部の正規表現を含む特定のシェル変数の場合。

バックスラッシュを含む場合は、$patternエスケープ処理(\\)する必要があります。または、次のものを使用できます。

P="$pattern" awk '$0 !~ ENVIRON["P"] || !n++' file.in

答え3

行が現れるたびにバッファを交換し、パターン空間に同じ行が含まれている場合は削除し、そうでない場合は保持されているバッファから行を検索します。

sed -e '/^AAA$/{x;//d;g' -e'}' infile

または

sed '/^AAA$/{
x
//d
g
}' infile

関連情報